用Matplotlib注释一个注释

9

我目前在Matplotlib中进行一些“花哨”的注释:

import matplotlib.pyplot as plt
ax = plt.subplot(111)
plt.axis('equal')
src_pos, dst_pos = (0, 0), (1, 1)
src_patch = plt.Rectangle(src_pos, .25, .25, color='r')
ax.add_patch(src_patch)
dst_patch = plt.Circle(dst_pos, .25, color='b')
ax.add_patch(dst_patch)
arrowprops = dict(
    arrowstyle='<-', 
    connectionstyle='arc3,rad=0.3', 
    patchA=dst_patch, 
    patchB=src_patch, 
    shrinkA=1, 
    shrinkB=1)
ant = ax.annotate('', src_pos, dst_pos, arrowprops=arrowprops)
plt.draw()
plt.show()

现在我想在箭头旁边添加一些文本。输出应该如下图所示:
[image]
我对一般解决方案感兴趣,其中文本放置是根据渲染器选择的箭头路径进行编程选择的。例如,
- 对于未知的src_pos和dst_pos值,应适当地放置文本。 - 无论如何设置arrowprops和使用哪种connectionstyle,都应适当地放置文本。 - 我希望在脚本结束之前不必调用plt.draw()。
谢谢!

1
请参见 https://gist.github.com/tacaswell/6337457。我认为你不能一次调用annotate完成它。 - tacaswell
@tcaswell - 感谢您的指引。就我而言,在 plt.show() 之前插入任何代码都可以解决这个问题。 - BrianTheLion
2个回答

2

只需查看http://matplotlib.org/users/annotations_intro.html页面即可。如果您知道坐标,似乎可以独立于箭头放置文本。在draw()命令之前添加以下内容:

ant2 = ax.annotate('this is\nthe text\ni want\nto add', xy=(0.1, 0.8), xytext=(0.1, 0.8), horizontalalignment='left', verticalalignment='top')

就一般解决方案而言,它将像原始注释一样复杂,因为根据给定的参数,会创建相当多不同种类的内容。例如,如果未指定箭头样式,则会创建一个YAArow patch实例。您可以调用YAArow的get_path()方法,但路径的实用性有限,因为它更或多或少只是点的集合。您需要编写一个“find_middle_of_path()”函数,该函数需要考虑到路径不一定需要连续,有时使用路径的方法并没有填充路径的所有属性等。当箭头路径被图形的边缘剪切时,箭头路径非连续的示例。
如果指定了箭头样式,则会创建一个FancyArrowPatch实例。如果创建了一个FancyArrowPatch,则可以调用get_path_in_displaycoord()来获取路径,与YAArow patch path的注意事项相同。
在我看来,您最好创建一些相当简单的程序,对于您真正想要使用注释的可能有限的方式,每次调用两次注释,一次用于箭头,一次用于文本。

请注意,我对一个通用解决方案很感兴趣。 - BrianTheLion
3
我可能错了,但我认为在matplotlib中没有现成的通用解决方案。如果您想要这个功能,我认为您需要使用这个答案自己添加它。 - Alexander Van Atta
1
@AlexanderVanAtta:Matplotlib 渲染器必须在某处存储箭头的路径数据。如果是这样,那么找到箭头(线性)中点在数据坐标系中的位置并将文本放置在那里应该很简单。 - BrianTheLion
1
@BrianTheLion 为什么会是这样呢?箭头是一个弧形,因此它不需要在坐标中存储整个路径,只需要起始点和弧形即可。拥有箭头并不意味着 matplotlib 轻松知道箭头的中点。 - Simeon Visser
@SimeonVisser 对不起,让我澄清一下:我不认为matplotlib“轻而易举地知道”箭头的中点,但我非常确定如果可以获得箭头的路径数据,则中点可以轻松计算。鉴于注释类源代码中提供的数据访问器,似乎可以合理地假设路径数据确实可用。 - BrianTheLion
1
正如我在更新的答案中所指出的那样,已经创建了一个路径对象,但它并不一定有用,因为它只是可见点的列表,并且必须根据箭头样式以不同的方式进行访问。 - Troy Rockwood

0

还有另一个选项text(),可以在已知位置添加任何文本到图中。 查看此链接获取额外选项

ant1 = ax.text(0.4, 0.6, 'text')

这与 arrowprops 无关


我正在寻找一种通用解决方案,其中定位点事先未知。 - BrianTheLion
1
您还可以动态计算文本的位置。由于数据点必须可用于绘图,因此您可以直观地计算放置文本的位置! - Thiru
不幸的是,Matplotlib允许的各种“花哨”的箭头样式并非如此。请参见http://matplotlib.org/users/plotting/examples/connectionstyle_demo.png。 - BrianTheLion

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