Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw good looking arrows in Matlab?

I have been trying to draw arrows in Matlab in my figure but they all look terrible. Also, I want my arrowhead to be a solid triangle, not a V.

I tried using the packages available on the Matlab File Exchange: arrow, arrows, arrows3, and probably at least one other one.

I even tried manually creating an arrow in the Matlab figure editor, but when I adjust the line width, the arrow looks like this:

enter image description here

I used the annotation command to create the arrow above:

annotation(gcf,'arrow',[0.621875 0.457916666666667],...
                       [0.205421152030217 0.40755429650614],...
                       'HeadLength',4,'LineWidth',5);

Here's the result trying to use the arrow package available here: Arrow.m (notice how the bottom arrow head is not perpendicular to the line:

enter image description here

I even tried the following and here is the result below (notice the terrible looking arrowhead):

 figure
 plot(1:10, 1:10)
 annotation(gcf,'arrow',[0.621875 0.457916666666667],...
                        [0.205421152030217 0.40755429650614],...
                        'HeadLength',4,'LineWidth',5);

enter image description here

like image 598
Veridian Avatar asked Aug 13 '13 16:08

Veridian


People also ask

How do I draw an arrow in Matlab?

You can use arrow from the file exchange. arrow(Start,Stop) draws a line with an arrow from Start to Stop (points should be vectors of length 2 or 3, or matrices with 2 or 3 columns), and returns the graphics handle of the arrow(s).

How do you annotate an arrow in Matlab?

Create Text Arrow AnnotationCreate a simple line plot and add a text arrow to the figure. Specify the text arrow location in normalized figure coordinates, starting at the point (0.3,0.6) and ending at (0.5,0.5) . Specify the text description by setting the String property.

How do you draw a diagram in Matlab?

plot( X , Y ) creates a 2-D line plot of the data in Y versus the corresponding values in X . To plot a set of coordinates connected by line segments, specify X and Y as vectors of the same length. To plot multiple sets of coordinates on the same set of axes, specify at least one of X or Y as a matrix.


3 Answers

Vector graphics is hard. Though Matlab's typography is just as bad, but here's a simplistic text-based solution (I refuse to do this sort of annotation in Matlab any more):

figure
plot(1:10, 1:10)
text(5,4,'\rightarrow','FontSize',54,'Rotation',135,...
         'HorizontalAlignment','center');

which yields a figure like this

                        enter image description here

Note that I have used '\leftarrow' because it points in the direction of zero degrees, which makes doing math in my head easier. This is no canned solution, you'll still need to fiddle with position to overcome the fact that Matlab is aligning this as text (see the 'Extent' and 'Margin' properties). Not surprisingly, you may see small glitches. The LaTeX interpreter can be used to obtain a different style arrow head:

    text(5,4,'$\rightarrow$','FontSize',54,'Rotation',135,...
             'HorizontalAlignment','center','Interpreter','latex');

I don't get the small glitches with this option, but the arrows look different (there are likely other LaTeX arrow styles that could be substituted). Changing the font may also have an effect and there are certainly other text-based arrows that could be used. More details on adding arrows can be found in this article from The MathWorks.

like image 113
horchler Avatar answered Sep 29 '22 17:09

horchler


Another solution is to use the open-source Waterloo graphics - a library that addresses this by providing a pure Java library of 2D graphics functions that can easily be integrated in Matlab. See some examples here...

For example, try this code (after properly installing waterloo)

f = GXFigure();
x = -5:0.1:5;
gr1 = gxgca();
a1 = line(gr1, x, cos(x), 'LineSpec','-ob');
b1 = line(gr1, x, sin(x), 'LineSpec','-sg');
annotation(gr1,'arrow',[0.1 0.1],[0.4 0.4],'HeadLength',0.2,'HeadWidth', 0.5, 'LineWidth',2);
gr1.getObject().getView().autoScale();

enter image description here

like image 23
bla Avatar answered Sep 29 '22 17:09

bla


Having worked with Matlab for more than 10 years and seeing almost zero progress in the quality of the plots (anti-aliased output to bitmap, decent looking eps-files, ...), I decided that my long time solution will be here. Some examples of decent looking arrows here, more beautiful graphs here. Unfortunately, some of the toolboxes prevent me from going completely to numpy/scipy/matplotlib. I know this is more of a rant than an answer, but that is my solution ...

like image 35
Bas Swinckels Avatar answered Sep 29 '22 16:09

Bas Swinckels