File Exchange

## Quiver - magnitude-dependent color in 2D and 3D

version 1.2 (4.57 KB) by
Implements the MATLAB given quiver/quiver3 function adding a color coding depending on magnitude

Updated 19 Jun 2020

%quiverC3D creates a 3D quiver plot and adds a color coding. The color coding is
%given by the magnitudes of the component vectors. Large values result in colors
%from the upper end of the used colormap.
%
% INPUT:
% x - array, x components of initial points
% y - array, y components of initial points
% z - array, z components of initial points
% u - array, x components of arrows
% v - array, y components of arrows
% w - array, z components of arrows
% scale - number, if > 0, automatic scaling is used to avoid overlap
% of adjacent arrows. If scale = 0, the scaling is disabled.
% MaxNumArrows - a positive integer (non-integer should work as well)
% number limiting the maximum number of plotted arrows. Since vectors
% of length zero aren't plotted and the matrices are sampled
% uniformly, it's possible that fewer arrows will be visible in the
% end. If MaxNumArrows is not given its value is set to inf.
%
% OUTPUT:
% none
%
% WARNING!: This function might not create arrows with the same length as
% would be obtained using quiver3(x, y, z, u, v, w). I do not know
% whether the scaling method is the same is in quiver3.
%
%
% --------------------------------------------------------------------------------------
%
% EXAMPLE:
% quiverC3D(x,y,z,u,v,w,1,1000);
% view(-45,20)
% set(gca, 'Color', 'black');
% axis tight
% axis equal
%
% --------------------------------------------------------------------------------------
%
%

### Cite As

Jonas Krimmer (2020). Quiver - magnitude-dependent color in 2D and 3D (https://www.mathworks.com/matlabcentral/fileexchange/58527-quiver-magnitude-dependent-color-in-2d-and-3d), MATLAB Central File Exchange. Retrieved .

Jingjing Meng

Jonas Krimmer

@Javier, thank you very much for your simple but very helpful implementation of a matching colorbar. I have included a slightly adapted version of your code in the newest update.

Best,
Jonas

Javier

@Jonas, thank you very much, it works and it is really usefull.
You can insert a (simple) colorbar just adding some lines at the end of your function:

MyColorBar=colorbar;
TickL=get(MyColorBar,'Ticklabels');
TickL=sprintfc('%1.3g ',((1:length(TickL))-1)*Imax/length(TickL));
set(MyColorBar,'TickLabels',TickL);

Best,
Javier

Jonas Krimmer

Hi Stefanos, I'm glad that my function is useful to you. Unfortunately, the coloring of the arrows is based on the truecolor values according to the colormap. While this approach is useful in some cases, it is not compatible with the standard colorbar. In the future, I would like to add a custom colorbar for this purpose.

stefanos theocharis

Dear Jonas thank you cery much for this function its been really usefull for writing my thesis. Could you please tell me how could the colormap corespond to the real magnitude of the 3d vector eg 2.7 and not has maximum 1.

rui Zeng

Jonas Krimmer

@Leo:
Glad you were successful! Unfortunately, I cannot do much for you concerning the colorbar. Since quiverC2D/quiverC3D use truecolor-coloring (which does not change with subsequent colormap changes), you currently have to generate your colorbar manually. However, this colorbar generation seems like a very useful feature and I will definitely implement it at some point if possible.
MaxHeadSize works fine for me, have you tried using a very small value such as 1e-5 (in case of my wind-example)? The vector density can be controlled to some extent via the maximum number of arrows. I have to admit that a more elegant approach would be desirable.
Best
Jonas

Leo Dang

@Jonas, thanks it works now! When I overlaid the vector map on top a grayscale image the gray scale is applied for the vectors as well, so I change to C = colormap() so that the vectors can have the default color scale, which worked. But if I wish to display colorbar it only uses the grayscale colormap of the background image, thus a grayscale colorbar. Any suggestion on how to display colorbar separately for the vector map? I also played with other parameters which worked fine except 'MaxHeadSize' had no effect, nor was there parameter for choosing vector density, e.g. current default is 1 vector/3 pixels, how would you suggest to get around this?

Jonas Krimmer

@Leo:

I guess the most simple fix for you will be to change verLessThan('matlab','9.6') to verLessThan('matlab','9.5') in both functions. The errors were caused by a missing pair of brackets in the old-matlab-release-fallback for the maximum calculation. I will upload an updated version with some additional changes to the length scaling in a minute. Thank you very much for your support in finding the cause of the error.

Leo Dang

@Jonas
I simply tried running this exact script with Matlab R2018b on Mac Mojave...
% clear all; close all; clc;
% quiverC2D(x(:,:,1),y(:,:,1),u(:,:,1),v(:,:,1),1);
% set(gca, 'Color', 'black');
% axis tight
% axis equal
load wind gives components u,v,w,x,y,z of same 35x41x15 double and when run the above script the error is:
------
Error using /
Matrix dimensions must agree.
Error in quiverC2D (line 104)
Ic = round(I/Imax*ncolors);
Error in TestCode3 (line 3)
quiverC2D(x(:,:,1),y(:,:,1),u(:,:,1),v(:,:,1),1);
------
Also when I tried the 3D example:
% quiverC3D(x,y,z,u,v,w,1,1000);
% view(-45,20)
% set(gca, 'Color', 'black');
% axis tight
% axis equal
The error is:
-----
Error using /
Arguments must be 2-D, or at least one argument must be scalar. Use RDIVIDE (./) for
elementwise right division.
Error in quiverC3D (line 109)
Ic = round(I/Imax*ncolors);
Error in TestCode3 (line 9)
quiverC3D(x,y,z,u,v,w,1,1000);
----
And if I go to quiverC3D.m to change Ic = round(I/Imax*ncolors); to Ic = round(I./Imax*ncolors); the error is:
----
Array dimensions must match for binary array op.
Error in quiverC3D (line 109)
Ic = round(I./Imax*ncolors);
Error in TestCode3 (line 9)
quiverC3D(x,y,z,u,v,w,1,1000);
-----
Nothing else in workspace except the 6 components in wind

Jonas Krimmer

@Leo Dang: Hi Leo, unfortunately I cannot reproduce your issue. Can you provide me with additional info on your system and the sizes of the relevant variables I, Imax, and ncolors prior to the occurrence of the error?
Best
Jonas

Leo Dang

Hi Jonas, when I tried the wind example with the 2D this is the error... any idea why?
--------------------------
Error using /
Matrix dimensions must agree.

Error in quiverC2D (line 104)
Ic = round(I/Imax*ncolors);

Jonas Krimmer

@David Robinson: That's probably because I had to turn off the automatic scaling of the quiver plots. The results should be the same as if you ran quiver(x, y, u, v, 0). Further, there was an automatic normalization enabled. Updated version is available with a more reasonable(?) normalization, which can easily be switched on and off!

David Robinson

Great function, but it does not appear to keep the integrity of the u and v magnitudes when plotting. The direction remains consistent, but a vector on the quiverC2D function has a different u and v component than the same vector has on the regular quiver function. Any idea why this may be?

Jonas Krimmer

@plasmageek: Honestly, I have no idea why there was this check for positive values included. It's been a while since I've written this function. Thank you for your remark, this condition is removed in the newest version.
If you would still need some help: Could you provide some more insight in what exactly you are trying to do? Otherwise, it will be hard to help you..

plasmageek

Hmm can't get this to work. It's not giving any errors, but all I get is a blank, white figure. I noticed there was a command checking for only positive values of the velocities (WHY??!!!??) and tried taking that out, but it still gives the same result.

Amlan Das

Hsin Chang