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