quiver3 color de la flecha correspondiente a la magnitud

Quiero que el color de cada flecha en una gráfica de quiver3 de MATLAB se corresponda con 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 diagtwig y quiero reemplazar las flechas azules con un color correspondiente a su magnitud.

enter image description here

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

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

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

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

enter image description here

Sin embargo, con la introducción de HG2 (R2014b y posterior), en realidad puede obtener acceso a dos objetos LineStrip (no documentados) ( matlab.graphics.primitive.world.LineStrip ) (uno representa las cabezas y el otro representa 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; 

A continuación, puede modificar las propiedades de color de estos objetos para que cada flecha tenga un color diferente.

La idea básica

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

 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 LineStrip ColorData ) también necesita tener un canal alfa (que estableceremos en 255 como opaco).

 cmap(:,:,4) = 255; 

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

Solución completa

NOTA: Esta solución funciona tanto para el quiver como para el 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).'); 

enter image description here

Y aplicado a un objeto quiver 2D

enter image description here

Si no quiere necesariamente 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 utilizando los límites de color de los ejes.

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

Si utiliza una versión posterior a la publicación 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 obtener la idea de cómo usar esta “característica”

enter image description here