matlab - quiver3 arrow color corresponding to magnitude -
i want color of each arrow in quiver3 plot matlab correspond magnitude of each arrow. there way that?
i saw few examples online able 2d quiver, none of them work 3d variant, quiver3.
i have following plot , want replace blue arrows color corresponding magnitude.

in old graphics system (r2014a , earlier) not possible using built-in quiver object. can of plot objects used compose quiver plot
q = quiver(1:5, 1:5, 1:5, 1:5); handles = findall(q, 'type', 'line'); but tails represented 1 plot object, , arrow heads represented another. such, can't alter color of each head/tail individually.
set(handles(1), 'color', 'r') set(handles(2), 'color', 'g') however, introduction of hg2 (r2014b , later), can access two (undocumented) linestrip objects (matlab.graphics.primitive.world.linestrip) (one represents heads , 1 represents tails). these accessible via hidden properties tail , head.
q = quiver(1, 1, 1, 1); headlinestrip = q.head; taillinestrip = q.tail; you can alter color properties of these objects make each arrow different color.
the basic idea
to this, first compute magnitude of quiver arrows (this works both quiver , quiver3)
mags = sqrt(sum(cat(2, q.udata(:), q.vdata(:), ... reshape(q.wdata, numel(q.udata), [])).^2, 2)); then use current colormap map each magnitude rgb value. shortest arrow assigned lowest color on colormap , longest arrow assigned highest color on colormap. histcounts works great assigning each magnitude index can passed ind2rgb along colormap itself. have multiply 255 because need color rgb 8-bit integer.
% current colormap currentcolormap = colormap(gca); % determine color make each arrow using colormap [~, ~, ind] = histcounts(mags, size(currentcolormap, 1)); % map colormap cmap = uint8(ind2rgb(ind(:), currentcolormap) * 255); the linestrip colordata property (when specified truecolor) needs have alpha channel (which set 255 meaning opaque).
cmap(:,:,4) = 255; at point can set colorbinding property interpolated rather object (to decouple quiver object) , set colordata property of both q.head , q.tail colors created above giving each arrow it's own color.
full solution
note: solution works both quiver , quiver3 , code not have adapted @ all.
%// create quiver3 (could 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 magnitude of vectors mags = sqrt(sum(cat(2, q.udata(:), q.vdata(:), ... reshape(q.wdata, numel(q.udata), [])).^2, 2)); %// current colormap currentcolormap = colormap(gca); %// determine color make each arrow using colormap [~, ~, ind] = histcounts(mags, size(currentcolormap, 1)); %// map colormap rgb cmap = uint8(ind2rgb(ind(:), currentcolormap) * 255); cmap(:,:,4) = 255; cmap = permute(repmat(cmap, [1 3 1]), [2 1 3]); %// 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).'); %' %// 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).'); and applied 2d quiver object
if don't want scale arrows entire range of colormap use following call histcounts (instead of line above) map magnitudes using color limits of axes.
clims = num2cell(get(gca, 'clim')); [~, ~, ind] = histcounts(mags, linspace(clims{:}, size(currentcolormap, 1))); 


Comments
Post a Comment