如何在Matlab中画出好看的箭头?

6
我一直在尝试在Matlab中绘制箭头,但它们看起来都很糟糕。另外,我想让我的箭头头部为一个实心三角形,而不是V形。
我尝试使用Matlab文件交换(Matlab File Exchange)上可用的软件包:arrow、arrows、arrows3,以及可能还有其他的。
我甚至尝试手动在Matlab图形编辑器中创建箭头,但当我调整线条宽度时,箭头看起来像这样:
[image]
我使用注释(annotation)命令创建了上面的箭头:
annotation(gcf,'arrow',[0.621875 0.457916666666667],...
                       [0.205421152030217 0.40755429650614],...
                       'HeadLength',4,'LineWidth',5);

这是使用此处提供的arrow包时的结果:Arrow.m(请注意,底部箭头不垂直于线条): enter image description here 我甚至尝试了以下方法,下面是结果(请注意可怕的箭头):
 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


1
花了太多太多太多的时间来解决这个问题。到目前为止,我想到的最好的答案是:下载并安装福昕阅读器,在那里注释PDF文件。 - Veridian
7个回答

4

矢量图形很难。虽然Matlab的排版也不如意,但这里有一个简单的基于文本的解决方案(我不再愿意在Matlab中进行此类注释):

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

这将产生这样的图形:

enter image description here

请注意,我使用了'\leftarrow',因为它指向零度方向,这使得在我的头脑中进行数学运算更加容易。这不是一个标准解决方案,您仍然需要调整位置以克服Matlab将其对齐为文本的事实(请参见'Extent''Margin'属性)。不出所料,您可能会看到一些小故障。可以使用LaTeX解释器来获取不同风格的箭头头部:

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

我不理解这个选项的小故障,但箭头看起来不同(可能可以替换其他的LaTeX箭头样式)。更改字体也可能会产生影响,当然还有其他基于文本的箭头可供使用。有关添加箭头的更多细节请参见The MathWorks的这篇文章

textarrow 与 arrow 存在相同的问题。 - Veridian
我想要一个三角形状的箭头。 - Veridian
可以做到。你只需要使用LaTeX(可能还需要安装额外的tex字体)。我没有说这会很容易。 - horchler
有没有办法让箭头变长? - Veridian
你不能拥有一切。我会使用包含填充三角形的字体(就像你想要的头部样式),然后将箭头的尾巴作为你所需粗细的线条添加进去。至今我还没有在Matlab中找到一个令人满意且通用的解决方案(即使是2-D箭头)来回答你的问题。我自己也很感兴趣。使用向量肯定是可行的,但需要工作和专业知识。 - horchler

4
另一种解决方案是使用开源的Waterloo graphics - 这是一个纯Java 2D图形函数库,可以轻松地集成到Matlab中。在这里可以看到一些例子here...
例如,请尝试此代码(在正确安装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


谢谢,我会研究一下的。字体和其他东西应该仍然看起来像常规的MATLAB吧? - Veridian
我应该如何绘制箭头? - Veridian
谢谢,不过我想要一支黑色箭头,带有一个尾巴,在非0、90、180或360度角度时保持其形状。 - Veridian
只需在注释行中添加 ...'color',[ 0 0 0] 即可。尝试探索其他句柄,看看如何实现你想要的功能。 - bla

3

我已经使用Matlab工作了10年以上,但是在绘图质量方面几乎没有任何进展(反锯齿输出到位图、漂亮的eps文件等)。因此,我决定采用 这里提供的长期解决方案。这里有一些漂亮的箭头示例(链接),更美丽的图表示例(链接)。不幸的是,一些工具箱阻止了我完全转向numpy/scipy/matplotlib。我知道这更像是发泄而不是答案,但这是我的解决方案...


我感谢您的回答。我刚刚一秒钟前安装了这个软件包,现在我不知道如何使用它。我需要在MATLAB中使用它还是它是独立的? - Veridian
不,它不是独立的,它是与numpy一起使用的绘图包,numpyPython脚本语言的库(一个真正的面向对象的脚本语言,具有可想象的任何任务的库)。scipy项目涵盖了Matlab的某些工具箱。有点陡峭的学习曲线,但非常值得。这是唯一的开源替代Matlab,几乎有一半的同事在使用它。忘记Octave/Scilab,NumPy/SciPy/Matplotlib/IPython才是未来... - Bas Swinckels
我在这个领域已经有15年的经验,但不幸的是,我只能同意这一点。Matlab可能擅长计算,但图形处理可能会成为一个噩梦。从我在实际使用中看到的HG2来看,未来也并不一定充满希望。 - horchler
我还没有安装成功。这只是为了画一条线而变得非常麻烦。由于 matplotlib、dateutil 和 ez_setup 的错误,这太荒谬了。是否有任何简单明了的指导? - Veridian
@natan的回答使用了Waterloo图形库。现在它不仅支持MATLAB、R、SciLab等语言,还支持Python。此外,通过提供可选的Groovy脚本引擎,它允许相同的图形代码在所有这些环境中运行,即无需编辑。 - user1610348
显示剩余3条评论

1

使用 quiver 或 quiver3 进行 3D 绘图肯定比你使用注释制作的最后一个箭头要好看。不过,它可能不会比你使用 Arrow.m 包制作的箭头更好看。如果你想的话,也可以在 quiver 上更改样式。


当我增加LineWidth时,Quiver制作了圆形箭头。 - Veridian
增加箭头大小可能很烦人。这样的东西行吗?http://www.mathworks.com/matlabcentral/fileexchange/34305-adjust-quiver-arrowhead-size - dynamo
也尝试过了,也没有帮助。 - Veridian

1
我选择安装InkScape并在其中绘制箭头。没有什么比它更简单和质量更好的了。

InkScape网站


0
现在有DaVinci Draw工具箱(完全透明:我编写/销售该工具箱),它使用低级Matlab命令,如plot()patch()来绘制中级形状,例如箭头。示例语法:
davinci( 'arrow', 'X',           [0 10],      ...
                  'Y',           [0 2],       ...
                  'Shaft.Width', 1,           ...
                  'Head.Length', 2.5,         ...
                  'Color',       'w',         ...
                  'EdgeColor',   'k',         ...
                  'LineWidth',   2.5 )

来自文档:

DaVinci arrow


0

当基于行的箭头失败时,您可以尝试基于补丁的箭头:

xArrow = [0 1 1 1.2 1 1 0];               % X-coords of arrow edge points
yArrow = [-0.1 -0.1 -0.2 0 0.2 0.1 0.1];  % Y-coords of arrow edge points
hArrow = fill(xArrow,yArrow, [1 0 0]);    % Plot a red arrow
axis equal                                % Set axis tick marks to be equal

enter image description here

虽然需要更多的工作,但你可以将上面的内容参数化为一个函数,该函数可以接受许多参数来调整箭头的缩放比例、长宽比、旋转角度和位置等。你甚至可以调整颜色、边线颜色和透明度。

François Beauducel 在他的文件交换提交中 ARROWS: generalized 2-D arrows plot 实现了这种想法。


你能解释一下你的答案吗? - Veridian
@starbox 你的问题之一是 y 轴上的对数缩放。这将扭曲基于补丁的箭头,这可能是为什么许多解决方案失败的原因。使用对数缩放找到一个通用解决方案可能会更加复杂。 - gnovice
我再次尝试使用那个箭头包,虽然我可以增加线宽,但是对于我给你的那些轴尺寸,箭头现在变得不可见了。 - Veridian
有没有办法解决那个扭曲问题?问题在于轴的尺寸,不一定是对数图。我测试过了。 - Veridian
@starbox 我暂时没有解决方案。我需要再深入研究一下。 - gnovice
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接