我还想在两个子图之间画一个箭头,但我什至不知道从哪里开始!但是,原始问题中子图示例之间的界线给了我足够的线索来开始......
首先,我将原始问题中的代码简化为一个最小的工作示例:
from matplotlib import lines, pyplot as plt
fig = plt.figure()
# First subplot
ax1 = fig.add_subplot(121)
plt.plot([0, 1], [0, 1])
# Second subplot
ax2 = fig.add_subplot(122)
plt.plot([0, 1], [0, 1])
# Add line from one subplot to the other
xyA = [0.5, 1.0]
ax1.plot(*xyA, "o")
xyB = [0.75, 0.25]
ax2.plot(*xyB, "o")
transFigure = fig.transFigure.inverted()
coord1 = transFigure.transform(ax1.transData.transform(xyA))
coord2 = transFigure.transform(ax2.transData.transform(xyB))
line = lines.Line2D(
(coord1[0], coord2[0]), # xdata
(coord1[1], coord2[1]), # ydata
transform=fig.transFigure,
color="black",
)
fig.lines.append(line)
# Show figure
plt.show()
这会产生以下输出:

然后,使用这篇博文,我认为答案是创建 amatplotlib.patches.FancyArrowPatch并将其附加到fig.patches(而不是创建 amatplotlib.lines.Line2D并将其附加到fig.lines)。在查阅了matplotlib.patches.FancyArrowPatch文档,加上一些试验和错误之后,我想出了一些在 matplotlib 3.1.2中有效的东西:
from matplotlib import patches, pyplot as plt
fig = plt.figure()
# First subplot
ax1 = fig.add_subplot(121)
plt.plot([0, 1], [0, 1])
# Second subplot
ax2 = fig.add_subplot(122)
plt.plot([0, 1], [0, 1])
# Add line from one subplot to the other
xyA = [0.5, 1.0]
ax1.plot(*xyA, "o")
xyB = [0.75, 0.25]
ax2.plot(*xyB, "o")
transFigure = fig.transFigure.inverted()
coord1 = transFigure.transform(ax1.transData.transform(xyA))
coord2 = transFigure.transform(ax2.transData.transform(xyB))
arrow = patches.FancyArrowPatch(
coord1, # posA
coord2, # posB
shrinkA=0, # so tail is exactly on posA (default shrink is 2)
shrinkB=0, # so head is exactly on posB (default shrink is 2)
transform=fig.transFigure,
color="black",
arrowstyle="-|>", # "normal" arrow
mutation_scale=30, # controls arrow head size
linewidth=3,
)
fig.patches.append(arrow)
# Show figure
plt.show()
但是,根据下面的评论,这在你得到这个的地方不起作用matplotlib 3.4.2:

请注意,箭头的末端不与目标点(橙色圆圈)对齐,这是他们应该做的。
此matplotlib版本更改也会导致原始行示例以相同的方式失败。
但是,有一个更好的补丁!使用ConnectionPatch( docs ),它是 的子类FancyArrowPatch,而不是FancyArrowPatch直接使用,因为它ConnectionPatch是专门为此用例设计的,并且更正确地处理转换,如本matplotlib文档示例所示:
fig = plt.figure()
# First subplot
ax1 = fig.add_subplot(121)
plt.plot([0, 1], [0, 1])
# Second subplot
ax2 = fig.add_subplot(122)
plt.plot([0, 1], [0, 1])
# Add line from one subplot to the other
xyA = [0.5, 1.0]
ax1.plot(*xyA, "o")
xyB = [0.75, 0.25]
ax2.plot(*xyB, "o")
# ConnectionPatch handles the transform internally so no need to get fig.transFigure
arrow = patches.ConnectionPatch(
xyA,
xyB,
coordsA=ax1.transData,
coordsB=ax2.transData,
# Default shrink parameter is 0 so can be omitted
color="black",
arrowstyle="-|>", # "normal" arrow
mutation_scale=30, # controls arrow head size
linewidth=3,
)
fig.patches.append(arrow)
# Show figure
plt.show()
这会在matplotlib 3.1.2和中产生正确的输出matplotlib 3.4.2,如下所示:

要绘制一条正确定位的线,连接 中的两个子图matplotlib 3.4.2,请使用ConnectionPatch如上但带有arrowstyle="-"(即没有箭头,所以只有一条线)的 a。
注意:您不能使用:
plt.arrow因为它会自动添加到当前坐标区,所以只出现在一个子图中
matplotlib.patches.Arrow由于轴-图形变换使箭头倾斜
matplotlib.patches.FancyArrow因为这也会导致倾斜的箭头