# How to draw an arrow using non normalized coordinates?

313 Ansichten (letzte 30 Tage)
Mr M. am 26 Jun. 2017
Bearbeitet: Bill Tubbs am 22 Mär. 2023
I use: annotation('arrow',X,Y), and I tried to change units, but it is always normalized. How to use data units?
##### 3 Kommentare2 ältere Kommentare anzeigen2 ältere Kommentare ausblenden
Mr M. am 28 Jun. 2017
yes, but I cannot figure out how to use non-normalized units with annotation('arrow')

Melden Sie sich an, um zu kommentieren.

### Antworten (9)

KarlHoff am 26 Jun. 2020
Bearbeitet: KarlHoff am 7 Aug. 2020
For me, using MATLAB R2018b,
the following works to produce an arrow at a location specified in data coordinates:
anArrow = annotation('arrow') ;
anArrow.Parent = gca; % or any other existing axes or figure
%EDIT thanks to @Moshe:
%anArrow.Position = [x_start, y_start, x_end, y_end] ;
anArrow.Position = [x_start, y_start, delta_x, delta_y] ;
The big advantage is that the arrow remains where it is with respect to other plot elements, even if the limits of the plot change afterwards.
This is not the case with all the approaches that convert data coordinates into other Units (Pixels, Inches, Normalized)
##### 3 Kommentare2 ältere Kommentare anzeigen2 ältere Kommentare ausblenden
German Elias Oggier am 13 Mai 2021
Thanks!

Melden Sie sich an, um zu kommentieren.

MICHAEL MUTWIRI am 21 Aug. 2021
Create the 'annotation' object for each subplot and edit their properties using dot notation.
For the X and Y properties you use similar values as your graph cordinates. The x-end and y_end are the tip of the arrow.
Below is a tested sample code
%Create sample data
x = linspace(0,2*pi,1e3);
y = sin(x); % Plotted of first subplot
z = cos(x); % Plotted of second subplot
fg1=figure(1);
% Specify different textarrows for different subplots
%%%**************** SUBPLOT 1 ********************
subplot(2,1,1);
plot(x,y,'k')
xlabel('x')
ylabel('Amplitude')
title('Sin(x)')
ylim([-1.1 1.1])
% Define X-Beginning and ending x-coordinates
x_start =pi-1;x_end = pi;
%Y- Beginning and ending y-coordinates
y_start =sin(x_end);y_end = sin(x_end);
anArrow = annotation('textarrow');
anArrow.Parent = gca;
anArrow.X = [x_start,x_end]; % set the x-property
anArrow.Y = [y_start ,y_end];
anArrow.String = 'sin(\pi)';
anArrow.Color = 'red';
%%%**************** SUBPLOT 2 ********************
subplot(2,1,2);
plot(x,z,'k')
xlabel('x')
ylabel('Amplitude ')
ylim([-1.1 1.1])
% Define X-Beginning and ending x-coordinates
x_start =1.5*pi-1;x_end = 1.5*pi;
%Y- Beginning and ending y-coordinates
y_start =cos(x_end);y_end = cos(x_end);
anArrow = annotation('textarrow');
anArrow.Parent = gca;
anArrow.X = [x_start,x_end]; % set the x-property
anArrow.Y = [y_start ,y_end];
anArrow.String = 'cos(3\pi/2)';
anArrow.Color = 'green'; ##### 1 KommentarKeine anzeigenKeine ausblenden
Bill Tubbs am 22 Mär. 2023
Bearbeitet: Bill Tubbs am 22 Mär. 2023
Thanks. This works. Strange that you can't use axes co-ordinate system with the annotate command. It has a 'Units' argument but I can't find an appropriate value for this argument other than the default which is 'normalized' (where is the documentation?).

Melden Sie sich an, um zu kommentieren.

Walter Roberson am 27 Jun. 2017
##### 8 Kommentare7 ältere Kommentare anzeigen7 ältere Kommentare ausblenden
Adam Danz am 11 Nov. 2019
Check out release notes for any updates on any release.

Melden Sie sich an, um zu kommentieren.

marcus yoder am 23 Aug. 2018
Bearbeitet: marcus yoder am 23 Aug. 2018
I tested the code by Walter Robinson and had to make a few changes to get it to work.
function obj = dataArrow(Xdata,Ydata,ax)
%This function will draw an arrow on the plot for the specified data.
%The inputs are
oldunits = get(ax, 'Units');
set(ax, 'Units', 'Normalized');
axpos = ax.CurrentAxes.Position;
set(ax, 'Units', oldunits);
%get axes drawing area in data units
ax_xlim = ax.CurrentAxes.XLim;
ax_ylim = ax.CurrentAxes.YLim;
ax_per_xdata = axpos(3) ./ diff(ax_xlim);
ax_per_ydata = axpos(4) ./ diff(ax_ylim);
%these are figure-relative
Xpixels = (Xdata - ax_xlim(1)) .* ax_per_xdata + axpos(1);
Ypixels = (Ydata - ax_ylim(1)) .* ax_per_ydata + axpos(2);
obj = annotation('arrow', Xpixels, Ypixels, 'Units', 'pixels');
end
##### 1 KommentarKeine anzeigenKeine ausblenden
Conrado Neto am 14 Apr. 2019
None of this work, actually

Melden Sie sich an, um zu kommentieren.

Robert am 7 Sep. 2019
I wanted to do something similar, here's an example that adds a double arrow between the x-values 1 and 5 with y-values 5 in a simple plot:
pos=[.1,.1,.85,.85];
figure;ax=axes('position',pos);plot(1:10)
x=[1,5];y=[5,5];
rx=xlim(ax);ry=ylim(ax);
cx=pos(3)/diff(rx);cy=pos(4)/diff(ry)
annotation('doublearrow',pos(1)+cx*(x-rx(1)),pos(2)+cy*(y-ry(1)))
##### 0 Kommentare-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

MichailM am 4 Apr. 2020
Maybe a function like the below could help. The x and y inputs are actual coordinates on the plot. Here I just need to draw an arrow but you can modify it
function myarrow(x,y)
ax = gca;
axpos = get(ax, 'Position');
X = get(gca,'XLim');
Y = get(gca,'YLim');
difX = X(2) - X(1);
difY = Y(2) - Y(1);
newx = x./difX;
newy = y./difY;
annotation('arrow',[newx(1)*axpos(3)+axpos(1) newx(2)*axpos(3)+axpos(1)],[newy(1)*axpos(4)+axpos(2) newy(2)*axpos(4)+axpos(2)])
end
##### 0 Kommentare-1 ältere Kommentare anzeigen-1 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

Marc Compere am 14 Aug. 2021
Scaling to achieve arrow annotations in axes units should be built into Matlab. The utility coord2norm() handles this easily.
This is a similar question with more discussions, but the short answer is: use coord2norm()
##### 1 KommentarKeine anzeigenKeine ausblenden
Adam Danz am 15 Aug. 2021
Thanks for pointing out that function, Marc, I'm sure it will be helpful in many cases.
Since it's a static, once-and-done, conversion, the annotation object may no longer be in the correct position if there are any changes to the figure size, axis size or position, axis limits, or aspect ratios. Calling the function after all plotting is complete would help to solve some of those issues. A more robust solution would be to assign listeners that update annotation objects when a resize or reposition event occurs but really what we need is for MathWorks to update the annotation function to support data units or offer users an alternative.

Melden Sie sich an, um zu kommentieren.

Vitaly Fedoseev am 26 Mai 2021
The following code (Matlab R2019a) draws an arrow in the plot coordinates from point P1 to point P2. Zoom in/out shifts position of the arrow:
P1=[10,-1]; %from point
P2=[70,2]; % to point
figure;
Xlim=[-1 110];
Ylim=[-2 3];
Pos = [0.10 0.55 0.85 0.4];
subplot('Position', Pos)
hold on
X_conv(1)=Pos(1)+(Pos(3))/(Xlim(2)-Xlim(1))*(P1(1)-Xlim(1));
X_conv(2)=Pos(1)+(Pos(3))/(Xlim(2)-Xlim(1))*(P2(1)-Xlim(1));
Y_conv(1)=Pos(2)+(Pos(4))/(Ylim(2)-Ylim(1))*(P1(2)-Ylim(1));
Y_conv(2)=Pos(2)+(Pos(4))/(Ylim(2)-Ylim(1))*(P2(2)-Ylim(1));
x=0:0.1:100;plot(x, sin(x));plot([-100 1000], P2(2)*[1 1]); plot(P2(1)*[1 1], [-100 100]);
plot(x, sin(x));plot([-100 1000], P1(2)*[1 1]); plot(P1(1)*[1 1], [-100 100])
xlim(Xlim)
ylim(Ylim)
annotation('arrow', X_conv, Y_conv) ##### 3 Kommentare2 ältere Kommentare anzeigen2 ältere Kommentare ausblenden
Walter Roberson am 1 Jun. 2021
It should not be added to the code. Adam is saying that if you wanted to illustrate that the arrow did not follow the axes, then you could delete the axes and observe that the arrow is still there.

Melden Sie sich an, um zu kommentieren.

Bruce Jackson am 26 Okt. 2022
It is absurd that we have to jump through hoops or download submitted code to plot an arrow in data units on a plot.
##### 2 Kommentare1 älteren Kommentar anzeigen1 älteren Kommentar ausblenden
Bruce Jackson am 27 Okt. 2022
Thanks for the suggestion, but I would like to place and point arrows with a specified length and direction. The innovative use of UNICODE arrows unfortunately doesn't allow for more than four or maybe eight directions, I expect.
[The excellent coord2norm() function, written by user sco1, should be part of core MATLAB and not require me to download and install third-party code, which I'm attempting to avoid to have a marketable toolbox.]

Melden Sie sich an, um zu kommentieren.

### Kategorien

Mehr zu Annotations finden Sie in Help Center und File Exchange

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!