Annotation 'arrow' head not aligned with arrow body
45 views (last 30 days)
Show older comments
Using the annotation 'arrow' to plot a nonlinear vector field. I have computed the components and derivatives for the two states I selected and they are held in the variables X, Y, U and V. The body of the arrow is aligned with the U V directional vectors, but all arrowheads are pointing directly to the left but and anchored on the end of the arrow line. Below is the code I'm using to create the arrow object and the handle to it, and using a 2d loop to go through my matrices.
ah = annotation('arrow',...
'headStyle','cback2','HeadLength',headLength,'HeadWidth',headWidth);
set(ah,'parent',gca);
set(ah,'position',[X(ii,ij) Y(ii,ij) LineLength*U(ii,ij) LineLength*V(ii,ij)]);
2 Comments
Felix Spitzer
on 20 Oct 2018
Moved: Walter Roberson
on 16 Sep 2024
Same Problem here. I have one Matlab file where it works fine and one where the same weird behaviour is observed. I have really no idea what I did different. Very strange, please fix!
Answers (2)
Patrick Fuchs
on 20 Jul 2021
This has to do with the way your axes are set up. There is probably some legacy code (pre Matlab 2006) computing the orientation of the arrowhead based on an assumption that your y axis is bottom to top and x axis is left to right (in ascending values).
As I can see from your plot your x axis runs descending from left to right. If you change this it should correct the arrow position. I've only ever experienced this problem with "imagesc" plots myself where the y-axis is inverted and a simple
set(gca,'YDir','normal')
clears it up for me. Maybe it is different in this case since it does not look like an imagesc axis but I still think the underlying issue is with how the "arrows" annotation (head) does not seem to work correctly when the axes are not standard cartesian orientation.
Hope this helps.
Bernard
on 14 Oct 2021
It looks like the angle of the arrow head is determined by the inverse tangent of dy/dx (the 4th and 3rd arguments of 'Position', respectively). So if your axes have different scales, the arrow head angle is not aligned with the line.
You can get around this by converting your engineering units to normalized units for the arrow. Could wrap this up in a function to expedite it.
%Original problem
plot(0:1000:10000, 0:0.1:1, 'bx-')
x1 = 4000;
x2 = 5000;
y1 = 0.6;
y2 = 0.5;
arh = annotation('arrow');
arh.Parent = gca;
arh.Position = [x1, y1, x2-x1, y2-y1];
arh.Color = 'r';
%Solution
x1 = 5000;
x2 = 6000;
y1 = 0.7;
y2 = 0.6;
xL = xlim;
yL = ylim;
ah = gca;
aPos = ah.Position;
ahx = [aPos(1), aPos(1)+aPos(3)];
ahy = [aPos(2), aPos(2)+aPos(4)];
x1p = interp1(xL, ahx, x1);
x2p = interp1(xL, ahx, x2);
y1p = interp1(yL, ahy, y1);
y2p = interp1(yL, ahy, y2);
arh2 = annotation('arrow');
arh2.Units = 'normalized';
arh2.Position = [x1p, y1p, x2p-x1p, y2p-y1p];
arh2.Color = 'k';
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!