How to make the quiver() arrow head size fixed?
470 views (last 30 days)
When I use the quiver() function to plot an arrow in my scatterplot, I noticed that the size of the arrow head is different, depending on how big the arrow itself is (its length basically).
Any ideas on how to make the arrow head size fixed independent of the arrow length? Or if it is at least possible to do?
V.G. de Bie on 14 Nov 2017
Just divide MaxHeadSize by the length of the arrow, then the heads will be the same size.
broken_arrow on 24 Sep 2021
Edited: broken_arrow on 27 Sep 2021
I agree quiver and quiver3 should have a built in option for constant arrow head size (@MathWorks Support Team). Dividing by the length doesn't work properly for me (doesn't really yield a constant head size). Here is a function I wrote to solve the problem for quiver3:
function out_arrowhandles =...
% Adds arrow heads with constant size to quiver3 plot.
% Arrow heads have the same inclination relative to the z plane as the vectors.
% Input arguments:
% in_quivhandle: Handle of quiver plot to be appended
% in_arrowheadlength: Desired arrow head length in vector length units
% in_arrowtipangle: Desired arrow head tip angle in degrees (°)
% Output arguments:
% out_arrowhandles: Handles to arrow head lines
X = reshape(in_quivhandle.XData,1,);
Y = reshape(in_quivhandle.YData,1,);
Z = reshape(in_quivhandle.ZData,1,);
U = reshape(in_quivhandle.UData,1,);
V = reshape(in_quivhandle.VData,1,);
W = reshape(in_quivhandle.WData,1,);
aux_Xend = X + U;
aux_Yend = Y + V;
aux_Zend = Z + W;
aux_orthvectors = cross([U;V;W],[U;V;W+1]);
aux_orthvectors = aux_orthvectors ./ vecnorm(aux_orthvectors);
aux_orthvectors(:,~any(aux_orthvectors,1)) = [1;0;0];
aux_arrowtips1 = in_arrowheadlength * (-[U;V;W] ./ vecnorm([U;V;W]) -...
aux_arrowtips2 = aux_arrowtips1 +...
aux_arrowhandle1 = quiver3(in_quivhandle.Parent,aux_Xend,aux_Yend,aux_Zend,...
aux_arrowhandle2 = quiver3(in_quivhandle.Parent,aux_Xend,aux_Yend,aux_Zend,...
out_arrowhandles = [aux_arrowhandle1 aux_arrowhandle2];
Run the function directly after quiver3 (with 'AutoScale' and 'ShowArrowHead' set to 'off') or combine both into a customquiver3 function if you want an all in one solution. To adapt the function for 2D quiver, append your 2D input vectors by Z=W=0 (cross only works on 3D vectors) and discard the z coordinate (0) before plotting. If you want a different inclination of the arrow heads, modify the cross product accordingly.
Also note that the arrow heads will look "skewed" if daspect of x and y axis differs.