**You are now following this question**

- You will see updates in your activity feed.
- You may receive emails, depending on your notification preferences.

17 views (last 30 days)

Show older comments

I have a graph for 3 variables as shown here. I know the saturation point co-ordinates and want arrows of the same color to be pointing them exactly like I have hand drawn in the figure. I tried annotations(arrow) function but it did not work even though I used correct co-ordinates it makes the arrow out of the boundary or maybe I was using it in a wrong way. Please help me if I can draw the arrows at a particular point I need. I would also have to declare 3 set of (x,y) co-odrinates since my main function needs to work simultanously for the three variables.

Code I tried:

plot(T,ih,T,iv,T,sh)

legend('Infected Human','Infected Mosquito','Susceptible Human','Location','east')

xlabel('Time (days)')

ylabel('Population')

x=[39636/40000 39636/40000];

y=[1 180/200];

annotation('arrow',x,y)

Thank you very much in advance.

the cyclist
on 15 May 2020

Abhishek Singh
on 15 May 2020

Rik
on 15 May 2020

Abhishek Singh
on 15 May 2020

Ameer Hamza
on 15 May 2020

annotation() takes position in figure() coordinates. The position has no relation with the x-values and y-values of your axes. If you want to specify the position of your arrows in the axes() coordinates, then you need to do a transformation. The following code shows an example. The arrow_x and arrow_y specify the position of arrows according to the x-axis and y-axis of the axes() and then use interp1 to do the transformation

fig = figure('Units', 'normalized');

ax = axes();

plot(1:10, 0.1:0.1:1);

pos = ax.Position;

pos(3:4) = pos(3:4) + pos(1:2);

arrow_x = [5 5];

arrow_y = [0.7 0.5];

arrow_x_fig = interp1(ax.XLim, pos([1 3]), arrow_x);

arrow_y_fig = interp1(ax.YLim, pos([2 4]), arrow_y);

annotation('arrow', arrow_x_fig, arrow_y_fig);

Abhishek Singh
on 16 May 2020

Do you mean I have transform my equation to set it in (0,1)?

I did not exactly understand what is being done here. Apologies for that.

pos = ax.Position;

pos(3:4) = pos(3:4) + pos(1:2);

Ameer Hamza
on 16 May 2020

No, you don't need to change your equation. My code shows you how you can specify the coordinates using your equation and convert it into the figure coordinates. Note that the figure coordinates vary between 0 and 1. (0,0) at the bottom left and (1,1) at the top right. The lines in your comments find the position of axes() in figure coordinates and then use the xlim and ylim of the axes to find the location in the figure coordinate. Note that I specified the position of arrow like this

arrow_x = [5 5];

arrow_y = [0.7 0.5];

The values are given according to my equation. The next two lines

arrow_x_fig = interp1(ax.XLim, pos([1 3]), arrow_x);

arrow_y_fig = interp1(ax.YLim, pos([2 4]), arrow_y);

These lines convert them to figure coordinate and return values between 0 and 1.

Abhishek Singh
on 16 May 2020

I searched for pos() and I think it is position but could not still understand how it is working here. Interp1 has to do with intercept but somehow I can not understand what these set of codes are collectively doing. Also what does pos(3:4) for example mean and what is the significance of this line specifically. I am not able to understand this line and hence the subsequent steps too.

pos(3:4) = pos(3:4) + pos(1:2);

Ameer Hamza
on 16 May 2020

pos() is not a MATLAB function. It is the name of the variable I created. In MATLAB, the coordinate of the figure window is normalized (because I used 'Units', 'normalized' in my code). (0,0) coordinate is the bottom-left corner, and (1,1) is top-right coordinate. All the points in between can be represented as pairs (x,y) both x and y are less than 1.

Since the axes() object exist inside the figure window. Therefore, it gets a position w.r.t. to figure the window. See here how the position of axes is defined: https://www.mathworks.com/help/matlab/ref/matlab.graphics.axis.axes-properties.html#budumk7_sep_shared-Position

pos(3:4) are the width and height of the axes. To the line [pos(3:4) + pos(1:2)] converts the height and width to the coordinate of the top-right corner of axes object.

interp1 is not used for intercept. It is used for interpolation. You can see some examples to learn how it works.

Abhishek Singh
on 16 May 2020

Ameer Hamza
on 16 May 2020

I would recommend running each line, see the output and search documentation until that output starts making sense. Alternatively, you can just treat it as a black box and encapsulate it in a function so that you can use it for your work now, and then you can understand it later. For example, create the following function file

function arrow_handle = myArrowFunction(ax, x, y)

pos = ax.Position;

pos(3:4) = pos(3:4) + pos(1:2);

X = interp1(ax.XLim, pos([1 3]), x);

Y = interp1(ax.YLim, pos([2 4]), y);

arrow_handle = annotation('arrow', X, Y);

end

and then you can call this function whenever you want to plot an arrow

fig = figure('Units', 'normalized');

ax = axes();

plot(1:10, 0.1:0.1:1);

arrow_x = [5 5];

arrow_y = [0.7 0.5];

myArrowFunction(ax, arrow_x, arrow_y);

Abhishek Singh
on 16 May 2020

I can use it as a function as you suggested but I do not understand the core of it. I mean very basic things like why is it pos(3:4) = pos(3:4) + pos(1:2); Why could it not be pos(4:5) = pos(3:4) + pos(1:2); I mean basically what do each entity mean inside it. I am looking at some sine cosine plots where they are using interp1. But I am not sure how interp1 function is using the pos here.

In short I am not able to translate it in the way I should do it for my code. You end points for x and y are (5 5) and (0.7 0.5) however mine are something like (39000 39000) and (200 180). So does it mean I have to transform these numbers to 1 ? That is the reason I am not able to understand how to translate them to my code. I checked a little bit about these functions and could not make sense of them.

Abhishek Singh
on 18 May 2020

Ameer Hamza
on 18 May 2020

This updated function is able to plot multiple arrows. You just need to specify the x-coordinates and y-coordinates of end-points of the arrows in arrow_x and arrow_y

fig = figure('Units', 'normalized');

ax = axes();

plot(1:10, 0.1:0.1:1);

arrow_x = [5 5; 6 5; 4 5];

arrow_y = [0.7 0.5; 0.7 0.5; 0.7 0.5];

myArrowFunction(ax, arrow_x, arrow_y);

function arrow_handle = myArrowFunction(ax, x, y)

pos = ax.Position;

pos(3:4) = pos(3:4) + pos(1:2);

X = interp1(ax.XLim, pos([1 3]), x);

Y = interp1(ax.YLim, pos([2 4]), y);

arrow_handle = gobjects(1, size(x,1));

for i=1:size(x,1)

arrow_handle(i) = annotation('arrow', X(i,:), Y(i,:));

end

end

Abhishek Singh
on 18 May 2020

Ameer Hamza
on 18 May 2020

Yes, you can treat it as a black box for now. The following shows how to pass colors to the annotation

fig = figure('Units', 'normalized');

ax = axes();

plot(1:10, 0.1:0.1:1);

arrow_x = [5 5; 6 5; 4 5];

arrow_y = [0.7 0.5; 0.7 0.5; 0.7 0.5];

colors = {[1 0 0], [0 1 0], [0 0 1]}; % RGB colors

myArrowFunction(ax, arrow_x, arrow_y, colors);

function arrow_handle = myArrowFunction(ax, x, y, colors)

pos = ax.Position;

pos(3:4) = pos(3:4) + pos(1:2);

X = interp1(ax.XLim, pos([1 3]), x);

Y = interp1(ax.YLim, pos([2 4]), y);

arrow_handle = gobjects(1, size(x,1));

for i=1:size(x,1)

arrow_handle(i) = annotation('arrow', X(i,:), Y(i,:), 'Color', colors{i});

end

end

Abhishek Singh
on 18 May 2020

Ameer Hamza
on 18 May 2020

Abhishek Singh
on 18 May 2020

Thanks Ameer. I think now I understand it. I am sorry that I did not read that link attentively in order to just solve this previously. Since left and width are associated with the x axis that is the reason 1 and 3 are used there and similarly for y axis. I also now understand a little what you meant by adding the pos(). I knew it was not function and it explores the axes position but now it makes a little sense to me.

Thank you very much.

G Dalzell
on 29 Jul 2021

Adam Danz
on 29 Jul 2021

Annotation support for data units has been requested numerous times over the years but has not been addressed by MathWorks.

Arrows can be added with the text() function which operates in data units. One option is using TeX markup,

hold on; xlim([0,1])

plot(.5, .5, 'o')

text(.5, .5, '\downarrow', 'FontSize', 24, 'VerticalAlignment', 'bottom', 'HorizontalAlignment','Center')

plot([.2 .8], [.5 .5], 's')

text(.2, .5, char(8595), 'FontSize', 24, 'VerticalAlignment', 'bottom', 'HorizontalAlignment','Center')

text(.8, .5, char(8675), 'FontSize', 24, 'VerticalAlignment', 'bottom', 'HorizontalAlignment','Center')

Rik
on 18 May 2020

A completely different strategy would be to use the LaTeX interpreter to insert an arrow as a text object:

x = 0:pi/20:2*pi;

y = sin(x);

plot(x,y)

text([pi pi*2],[0 0],'\downarrow',...

'FontSize',40,...

'VerticalAlignment','bottom','HorizontalAlignment','center')

Abhishek Singh
on 18 May 2020

I tried this and it works. I did not exactly understand what you meant by LaTex interpreter here?

Adam Danz
on 18 May 2020

I prefer this method to the annotation method since there isn't a need for coordinate transformation.

Here are some additional arrows to try out using Rik's example but they require explicitly setting the interpretter to latex.

text([pi pi*2],[0 0],'\big\downarrow','Interpreter','Latex', ... )

... '\Big\downarrow' ...

... '\bigg\downarrow' ...

... '\Bigg\downarrow' ...

Abhishek Singh
on 18 May 2020

Thanks Adam and Rik. So it would also work for multiple set of co-ordinates?

Adam Danz
on 18 May 2020

Rik's example uses >1 coordinate.

The best way to get that answer is just trying it :)

text(0:.1:1,0:.1:1,'\downarrow')

Abhishek Singh
on 18 May 2020

Adam Danz
on 18 May 2020

% For 1 color used in all arrows

th = text(0:.1:1,0:.1:1,'\downarrow','color','r');

% To define the color of each arrow.

th = text(0:.1:1,0:.1:1,'\downarrow');

colors = jet(11); % Generate the color matrix any way you want.

% The color matrix must have the same number of rows as arrows.

set(th,{'Color'}, mat2cell(colors,ones(size(colors,1),1),3))

Abhishek Singh
on 19 May 2020

Adam Danz
on 19 May 2020

doc jet

That will show you what jet is.

The matrix is n x 3 for n arrows. The 3 columns are normalized values of [red,green,blue] to produce 1 color per row. If you search the documentation on RGB color vectors you'll get lots of info.

Abhishek Singh
on 19 May 2020

Adam Danz
on 19 May 2020

Abhishek Singh
on 22 May 2020

Abhishek Singh
on 22 May 2020

Hi Adam, I used HSV and got the desired colors. Thank you very much to both of you :)

Adam Danz
on 22 May 2020

Glad I could help.

By the way, red, blue green would be

c = [ 1 0 0;

0 0 1;

0 1 0];

Abhishek Singh
on 24 May 2020

Rik
on 24 May 2020

A colormap is a three-column array. The columns are the intensity of red green and blue on a scale from 0 to 1. Every row is a color in your map.

Given this definition, I don't really understand what you mean.

Abhishek Singh
on 24 May 2020

Adam Danz
on 24 May 2020

jet(n) produces an nx3 matrix of R,G,B color values. The range of colors is always the same. The only input, n, controls the interval.

I recommended running "doc jet" which explains this. As I mentioned earlier, you can create any color map with an nx3 matrix of values between 0 and 1.

Red is [1 0 0] because it's 100% red, 0% green, 0% blue.

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

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)