How to plot arrow with data coordinates in Matlab?

70,156

Solution 1

I've just discovered this method, since I don't want to have to bother with normalised units. Use the latex interpreter:

figure
plot([1:5],[1:5]*3,'.-')
%// Say I want to put an arrow pointing to the location, [3 9]    
text(2.94,8.3,'\uparrow','fontsize',20)
text(2.8,7.8,'point [3,9]')

To make the arrow longer, use a larger fontsize.

Pros

  • Easier, faster and quicker than using normalised units
  • Don't need to install any functions (good for us lazy people..)
  • making use of the LaTeX interpreter, there is a whole range of arrows (up, down, left, right and other angles (see Symbol list)

Cons

  • Definitely needs trial and error/tweaking to get the correct location of the arrow head relative to the POI.
  • There is limited control over the length of the arrow
  • Some latex commands aren't understood by the interpreter (boo).

Solution 2

For the positioning of annotations, Matlab offers the function dsxy2figxy to convert data space points to normalized space coordinates. However, for whatever reasons, the function is not included in the Matlab distribution and has to be "created" first.

Copy the following line into the command window and execute it to open the function in your editor.

edit(fullfile(docroot,'techdoc','creating_plots','examples','dsxy2figxy.m'))

To use the function dsxy2figxy save it somewhere in your matlab search path.

Please find the full instructions for the function dsxy2figxy at matlab-central: http://www.mathworks.de/help/techdoc/creating_plots/bquk5ia-1.html

Solution 3

Even though annotation uses normalized as default units, you can associate these objects to the current axes (gca) and use data units for setting X and Y properties.

Here is an example of plotting a single arrow.

plot(1:10);
ha = annotation('arrow');  % store the arrow information in ha
ha.Parent = gca;           % associate the arrow the the current axes
ha.X = [5.5 5.5];          % the location in data units
ha.Y = [2 8];   

ha.LineWidth  = 3;          % make the arrow bolder for the picture
ha.HeadWidth  = 30;
ha.HeadLength = 30;

enter image description here

Solution 4

For anyone who comes across this topic looking to draw arrows in "data space" rather than in units relative to the figure and/or axes, I highly recommend arrow.m from the file exchange.

Solution 5

If I remember correctly you need to calculate the position of the axes in relation to the figure.

it should go like:

%% example plot
clf
plot(rand(5,2)*5)
%% get info specific to the axes you plan to plot into
set(gcf,'Units','normalized')
set(gca,'Units','normalized')
ax = axis;
ap = get(gca,'Position')
%% annotation from 1,2 to 3,4
xo = [1,3];
yo = [2,4];
xp = (xo-ax(1))/(ax(2)-ax(1))*ap(3)+ap(1);
yp = (yo-ax(3))/(ax(4)-ax(3))*ap(4)+ap(2);
ah=annotation('arrow',xp,yp,'Color','r');

Note Fixed offset in original calculation - ap(3),ap(4) are width and height of gca, not corner positions

Share:
70,156
datcn
Author by

datcn

Updated on January 31, 2020

Comments

  • datcn
    datcn over 4 years

    I know there is a function named annotation can plot arrows or double arrows. But annotation can only plot in normalized unit. For example:

    annotation('arrows',[x1 x2],[y1 y2])
    

    Here, [x1, x2] should be a ratio number less than one.

    So, my question is how can I plot arrows with a true value rather than a normalized value?

    I wonder if there is any other function can approach this or is there any function I can get the axis value of the figure so that I can adjust the true value into a normalized value.