在matplotlib中用一个文本标注多个点
我想用一段文字来标注多个数据点,并用几根箭头指向它们。我找到了一种简单的解决办法:
ax = plt.gca()
ax.plot([1,2,3,4],[1,4,2,6])
an1 = ax.annotate('Test',
xy=(2,4), xycoords='data',
xytext=(30,-80), textcoords='offset points',
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
fc="w"))
an2 = ax.annotate('Test',
xy=(3,2), xycoords='data',
xytext=(0,0), textcoords=an1,
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
fc="w"))
plt.show()
这样就得到了以下效果:

不过我其实不太喜欢这个方法,因为它看起来...嗯,像个丑陋的临时解决方案。
而且,这种方法还会影响标注的外观(主要是如果使用半透明的框框等等)。
所以,如果有人有更好的解决办法,或者至少有个想法怎么实现,请分享一下。
2 个回答
2
我个人会使用设置坐标轴的比例坐标来确保文本标签的位置,然后通过调整颜色的参数,让除了一个标签以外的其他标签都不可见。
ax = plt.gca()
ax.plot([1,2,3,4],[1,4,2,6])
label_frac_x = 0.35
label_frac_y = 0.2
#label first point
ax.annotate('Test',
xy=(2,4), xycoords='data', color='white',
xytext=(label_frac_x,label_frac_y), textcoords='axes fraction',
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
fc="w"))
#label second point
ax.annotate('Test',
xy=(3,2), xycoords='data', color='black',
xytext=(label_frac_x, label_frac_y), textcoords='axes fraction',
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
fc="w"))
plt.show()
17
我想要的正确解决方案可能需要花费很多精力——也就是自己去扩展一下 _AnnotateBase 类,并添加对多个箭头的支持。不过,我找到了一种简单的方法来解决第二个注释影响视觉效果的问题,只需加上 alpha=0.0
就可以了。所以,如果没有人提供更好的方法,这里是更新后的解决方案:
def my_annotate(ax, s, xy_arr=[], *args, **kwargs):
ans = []
an = ax.annotate(s, xy_arr[0], *args, **kwargs)
ans.append(an)
d = {}
try:
d['xycoords'] = kwargs['xycoords']
except KeyError:
pass
try:
d['arrowprops'] = kwargs['arrowprops']
except KeyError:
pass
for xy in xy_arr[1:]:
an = ax.annotate(s, xy, alpha=0.0, xytext=(0,0), textcoords=an, **d)
ans.append(an)
return ans
ax = plt.gca()
ax.plot([1,2,3,4],[1,4,2,6])
my_annotate(ax,
'Test',
xy_arr=[(2,4), (3,2), (4,6)], xycoords='data',
xytext=(30, -80), textcoords='offset points',
bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
arrowprops=dict(arrowstyle="-|>",
connectionstyle="arc3,rad=0.2",
fc="w"))
plt.show()
最终的效果图: