matlab matlab-figure

matlab - quiver3 color de flecha correspondiente a la magnitud



matlab-figure (2)

En el antiguo sistema de gráficos (R2014a y anterior) esto no es posible utilizando el objeto de quiver incorporado. Puede obtener fácilmente todos los objetos de trazado que se utilizan para componer el trazado de quiver

q = quiver(1:5, 1:5, 1:5, 1:5); handles = findall(q, ''type'', ''line'');

Pero todas las colas están representadas por un objeto de trazado y las puntas de flecha están representadas por otro. Como tal, no puede alterar el color de cada cabeza / cola individualmente .

set(handles(1), ''Color'', ''r'') set(handles(2), ''Color'', ''g'')

Sin embargo, con la introducción de HG2 (R2014b y posterior), puede obtener acceso a dos objetos LineStrip (no documentados) ( matlab.graphics.primitive.world.LineStrip ) (uno representa las cabezas y el otro las colas). Estos son accesibles a través de las propiedades ocultas Tail y Head .

q = quiver(1, 1, 1, 1); headLineStrip = q.Head; tailLineStrip = q.Tail;

Luego puede modificar las propiedades de color de estos objetos para hacer que cada flecha tenga un color diferente.

La idea basica

Para hacer esto, primero calculo la magnitud de todas las flechas de carcaj (esto funciona tanto para quiver como para quiver3 )

mags = sqrt(sum(cat(2, q.UData(:), q.VData(:), ... reshape(q.WData, numel(q.UData), [])).^2, 2));

Luego uso el mapa de colores actual para asignar cada magnitud a un valor RGB. A la flecha más corta se le asigna el color más bajo en el mapa de colores y a la flecha más larga se le asigna el color más alto en el mapa de colores. histcounts funciona muy bien para asignar a cada magnitud un índice que se puede pasar a ind2rgb junto con el mapa de ind2rgb en sí. Tenemos que multiplicar por 255 porque necesitamos que el color sea RGB como un entero de 8 bits.

% Get the current colormap currentColormap = colormap(gca); % Now determine the color to make each arrow using a colormap [~, ~, ind] = histcounts(mags, size(currentColormap, 1)); % Now map this to a colormap cmap = uint8(ind2rgb(ind(:), currentColormap) * 255);

La propiedad LineStrip ColorData (cuando se especifica como truecolor ) también debe tener un canal alfa (que estableceremos en 255, que significa opaco).

cmap(:,:,4) = 255;

En este punto, podemos establecer la propiedad ColorBinding para interpolated lugar de object (para desacoplarla del objeto quiver ) y establecer la propiedad ColorData de q.Head y q.Tail a los colores que creamos arriba, dando a cada flecha su propio color .

Solución completa

NOTA: Esta solución funciona tanto para quiver como para quiver3 y el código no tiene que adaptarse en absoluto.

%// Create a quiver3 as we normally would (could also be 2D quiver) x = 1:10; y = 1:10; [X,Y] = meshgrid(x, y); Z = zeros(size(X)); U = zeros(size(X)); V = zeros(size(X)); W = sqrt(X.^2 + Y.^2); q = quiver3(X, Y, Z, U, V, W); %// Compute the magnitude of the vectors mags = sqrt(sum(cat(2, q.UData(:), q.VData(:), ... reshape(q.WData, numel(q.UData), [])).^2, 2)); %// Get the current colormap currentColormap = colormap(gca); %// Now determine the color to make each arrow using a colormap [~, ~, ind] = histcounts(mags, size(currentColormap, 1)); %// Now map this to a colormap to get RGB cmap = uint8(ind2rgb(ind(:), currentColormap) * 255); cmap(:,:,4) = 255; cmap = permute(repmat(cmap, [1 3 1]), [2 1 3]); %// We repeat each color 3 times (using 1:3 below) because each arrow has 3 vertices set(q.Head, ... ''ColorBinding'', ''interpolated'', ... ''ColorData'', reshape(cmap(1:3,:,:), [], 4).''); %'' %// We repeat each color 2 times (using 1:2 below) because each tail has 2 vertices set(q.Tail, ... ''ColorBinding'', ''interpolated'', ... ''ColorData'', reshape(cmap(1:2,:,:), [], 4).'');

Y aplicado a un objeto de quiver 2D

Si no necesariamente desea escalar las flechas a todo el rango del mapa de colores, puede usar la siguiente llamada a histcounts (en lugar de la línea anterior) para mapear las magnitudes usando los límites de color de los ejes.

clims = num2cell(get(gca, ''clim'')); [~, ~, ind] = histcounts(mags, linspace(clims{:}, size(currentColormap, 1)));

Quiero que el color de cada flecha en un gráfico de quiver3 de MATLAB corresponda a la magnitud de cada flecha. ¿Hay alguna forma de hacer eso?

Vi algunos ejemplos en línea que pueden hacer esto para el quiver 2D, sin embargo ninguno de ellos funciona para la variante 3D, quiver3 .

Tengo el siguiente diagrama y quiero reemplazar las flechas azules con un color correspondiente a su magnitud.


Si usa una versión posterior a r2014b, puede usar funciones no documentadas para cambiar el color de cada línea y encabezado:

figure [x,y] = meshgrid(-2:.5:2,-1:.5:1); z = x .* exp(-x.^2 - y.^2); [u,v,w] = surfnorm(x,y,z); h=quiver3(x,y,z,u,v,w); s = size(x); nPoints = s(1)*s(2); % create a colour map cmap = parula(nPoints); % x2 because each point has 2 points, a start and an end. cd = uint8(repmat([255 0 0 255]'', 1, nPoints*2)); count = 0; % we need to assign a colour per point for ii=1:nPoints % and we need to assign a colour to the start and end of the % line. for jj=1:2 count = count + 1; cd(1:3,count) = uint8(255*cmap(ii,:)''); end end % set the colour binding method and the colour data of the tail set(h.Tail, ''ColorBinding'',''interpolated'', ''ColorData'',cd) % create a color matrix for the heads cd = uint8(repmat([255 0 0 255]'', 1, nPoints*3)); count = 0; % we need to assign a colour per point for ii=1:nPoints % and we need to assign a colour to the all the points % at the head of the arrow for jj=1:3 count = count + 1; cd(1:3,count) = uint8(255*cmap(ii,:)''); end end % set the colour binding method and the colour data of the head set(h.Head, ''ColorBinding'',''interpolated'', ''ColorData'',cd)

Nota: No he hecho nada inteligente con la magnitud y simplemente cambio el color de cada carcaj en función del orden en la matriz original, pero debería poder hacerse una idea de cómo usar esta "función"