Python 获取Matplotlib注释中箭头的坐标

Python 获取Matplotlib注释中箭头的坐标,python,matplotlib,Python,Matplotlib,从下面开始,我在figure fraction坐标中获得文本标签框的坐标,并尝试以相同的方式获得箭头补丁的坐标 但我得到的坐标与箭头不对应,因为当我在同一坐标上画一条线时,它并不在上面: 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*n

从下面开始,我在figure fraction坐标中获得文本标签框的坐标,并尝试以相同的方式获得箭头补丁的坐标

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

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')

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

你差不多到了,你有箭头边界框的坐标,即使用箭头作为对角线绘制的框。从中,我们可以找到头/尾坐标

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

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)
结果如下图所示:


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

line = Line2D(leader_line_box.T[0][::-1], leader_line_box.T[1],transform=fig.transFigure, lw=2, color='m')
如果你需要一个更通用的解决方案

verts = ann.arrow_patch.get_path()._vertices
tverts= fig.transFigure.inverted().transform(verts)  
index = [0,2]
line = Line2D([tverts[index[0],0],tverts[index[1],0]], [tverts[index[0],1],tverts[index[1],1]],
              transform=fig.transFigure, lw=2, color='m')
ax.add_line(line)
这适用于任何指向上或下、东或西的箭头方向,但特定于arrowprops参数arrowstyle='->'和connectionstyle=arc3。使用不同的箭头样式或连接样式需要将索引设置为不同的值,这些值可以通过从存储在顶点中的数组中选择适当的索引来找到

在一个非常普遍的情况下,我们还可以看到以下内容:

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)

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

我认为它正是按照您的要求做的:从箭头边界框的左下角到右上角绘制一条线。如果要使该行与箭头对齐,只需将[:-1]置于扩展数据或ydata的相反位置即可。这些不是你要找的坐标吗?你想把线画在哪里?嗯,我想你是对的。我真正想要的是箭头的尾部和头部的坐标。