matplotlib 如何制作非xkcd风格化的注解箭头

u1ehiz5o  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(106)

我使用的是matplotlib 3.7.1版本,默认的注解箭头似乎是按照xkcd样式化的。下面是一个简单的图来说明这一点:

  1. fig, ax = plt.subplots(1, 1, figsize=(6, 6))
  2. p1 = 0.3
  3. p2 = 0.7
  4. ax.axvline(p1, color='k', linestyle='solid')
  5. ax.axvline(p2, color='k', linestyle='solid')
  6. ax.annotate('blah', xy=(p1, 0.75), xytext=(p2, 0.75),
  7. arrowprops=dict(arrowstyle='<->')
  8. )
  9. ax.set_ylim(0, 1.1)
  10. ax.set_xlim(0, 1)
  11. plt.show()

请注意,这条线既不是直的也不是水平的,箭头也没有跨越整个距离。请注意,我没有启用此功能,它似乎是默认的。matplotlib注解库使它看起来像是预期的结果。我想关闭所有这些并获得直线。
编辑:为了回应一条评论说这条线是直的,下面是绘制水平线的代码,指向/来自相同点的直箭头(红色):

  1. fig, ax = plt.subplots(1, 1, figsize=(6, 6))
  2. p1 = 0.3
  3. p2 = 0.7
  4. ax.axvline(p1, color='k', linestyle='solid')
  5. ax.axvline(p2, color='k', linestyle='solid')
  6. ax.arrow(p1, 0.75, p2 - p1, 0, length_includes_head=True,
  7. head_width=0.1, head_length=0.01, facecolor='none',
  8. overhang=1, edgecolor='r', alpha=0.5)
  9. ax.arrow(p2, 0.75, p1 - p2, 0, length_includes_head=True,
  10. head_width=0.1, head_length=0.01, facecolor='none',
  11. overhang=1, edgecolor='r', alpha=0.5)
  12. ax.annotate('blah', xy=(p1, 0.75), xytext=(p2, 0.75),
  13. arrowprops=dict(arrowstyle='<->')
  14. )
  15. ax.set_ylim(0, 1.1)
  16. ax.set_xlim(0, 1)
  17. plt.show()

注解线显然既不是直的(它会摆动)也不是水平的。无论如何,也许这是按预期的方式工作的,但这并不重要,要回答的问题是如何使用annotate得到直的、水平的线。

5tmbdcev

5tmbdcev1#

正如注解中所述,这条线是直的,只是有Angular 。原因是垂直对齐的文本拉箭头。如果你添加va="center"(你也可以使用整个名称,"verticalalignment"),这条线将是直的。
至于箭头没有一直指向线条,这是因为两个原因。
1.有箭头属性shrinkAshrinkB控制起始和结束偏移,默认设置为2点(在documentation中搜索“shrinkA”)。设置shrinkB=0将导致左箭头接触线。至于右箭头...
1.由于起始坐标指定了(在本例中)文本的左边缘。要避免出现此空格,您可以调整坐标以使箭头在垂直线处结束,或者创建两个注解,一个用于没有任何文本的箭头(只是把文本作为一个空字符串)和另一个只有文本。(可能还有另一种方式,我不知道。)
在这里,我对垂直对齐和两个收缩值进行了更改(尽管shrinkA不会将箭头带到线上,但它至少会使它更接近)。

  1. import matplotlib.pyplot as plt
  2. fig, ax = plt.subplots(1, 1, figsize=(6, 6))
  3. p1 = 0.3
  4. p2 = 0.7
  5. y = 0.75
  6. ax.axvline(p1, color="k", linestyle="solid")
  7. ax.axvline(p2, color="k", linestyle="solid")
  8. ax.hlines(y, p1, p2, "r", alpha=0.5) # proves the line is now horizontal
  9. ax.annotate("blah",
  10. xy=(p1, 0.75),
  11. xytext=(p2, 0.75),
  12. va="center",
  13. arrowprops=dict(arrowstyle="<->", shrinkA=0, shrinkB=0)
  14. )
  15. ax.set_ylim(0, 1.1)
  16. ax.set_xlim(0, 1)
  17. plt.show()

编辑:需要说明的是,默认样式不是xkcd样式。在文档中看起来是这样的原因是因为他们用connectionstyle="arc3,rad=-0.05"关键字参数为每个箭头路径添加了一个小曲线。文档真的不应该这样做,因为它没有显示默认功能,似乎暗示箭头通常是弯曲的。

展开查看全部

相关问题