获取Matplotlib注释中箭头的坐标

2024-04-28 00:06:15 发布

您现在位置:Python中文网/ 问答频道 /正文

my previous question开始,我得到了图分数坐标中文本标签框的坐标,并尝试以相同的方式获得箭头块的坐标。在

但是我得到的坐标与箭头不符,因为当我在同一个坐标上画一条线时,它并不在上面:

import numpy as np
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt

def f(x):
    return 10 * np.sin(3*x)**4

x = np.linspace(0, 2*np.pi, 100)
y = f(x)

fig, ax = plt.subplots()
ax.plot(x,y)

xpt = 1.75
ypt = f(xpt)
xy = ax.transData.transform([xpt, ypt])
xy = fig.transFigure.inverted().transform(xy)

xytext = xy + [0.1, -0.1]
rdx, rdy = 0, 1
ann = ax.annotate('A point', xy=xy, xycoords='figure fraction',
             xytext=xytext, textcoords='figure fraction',
             arrowprops=dict(arrowstyle='->', connectionstyle="arc3",
                             relpos=(rdx, rdy)),
             bbox=dict(fc='gray', edgecolor='k', alpha=0.5),
             ha='left', va='top'
            )
fig.canvas.draw()

leader_line_box = ann.arrow_patch.get_extents()
print(leader_line_box)
leader_line_box = fig.transFigure.inverted().transform(leader_line_box) 
print(leader_line_box)

from matplotlib.lines import Line2D
line = Line2D(leader_line_box.T[0], leader_line_box.T[1],transform=fig.transFigure, lw=2, color='m')
ax.add_line(line)

plt.savefig('test.png')

enter image description here

如何以图形分数单位获得注释箭头的((x0,y0), (x1,y1))坐标,以及我在这里的尝试中出了什么问题?在


Tags: importboxmatplotlibnplinefigtransformplt
2条回答

在这种非常特殊的情况下,最简单的方法就是反向绘制x坐标

line = Line2D(leader_line_box.T[0][::-1], leader_line_box.T[1],transform=fig.transFigure, lw=2, color='m')

如果你需要一个更普遍的解决方案

^{pr2}$

这适用于任何箭头方向(指向上或下、东或西),但特定于arrowprops参数{}和{}。使用不同的arrowstyle或connection样式将需要将index设置为不同的值,这些值可以通过从存储在verts中的数组中选择适当的索引来找到。在


在一个非常普遍的情况下,我们还可以看看以下几点:
box = ann.arrow_patch._posA_posB
tbox = fig.transFigure.inverted().transform(leader_line_box)
print tbox
line = Line2D(tbox.T[0], tbox.T[1],transform=fig.transFigure)

但是,这将使您得到注释点和文本本身之间的线。通常,这条线可能与实际箭头不同,这取决于所使用的箭头样式。在

你就快到了,你有箭头边界框的坐标,这个框是用箭头作为对角线绘制的框。我们可以从头部/尾部找到坐标。在

边界框坐标按[[left, bottom], [right, top]]顺序给出。在这里,箭头在左上角,尾在右下角。所以我们可以画两条线来直观地标记这些。将代码中的该部分替换为:

from matplotlib.lines import Line2D
dl = 0.01 # some arbitrary length for the marker line
head = [leader_line_box.T[0][0], leader_line_box.T[1][1]]
line_head = Line2D([head[0],head[0]+dl], [head[1],head[1]+dl],
    transform=fig.transFigure, lw=2, color='r') # mark head with red
ax.add_line(line_head)

tail = [leader_line_box.T[0][1], leader_line_box.T[1][0]]
line_tail = Line2D([tail[0],tail[0]+dl], [tail[1],tail[1]+dl],
    transform=fig.transFigure, lw=2, color='g') # mark tail with green
ax.add_line(line_tail)

结果如下图:

plot with arrow head and tail marked

相关问题 更多 >