从数据到图形坐标的转换

Transform from data to figure coordinates

this post, I would like to transform my data coordinates to figure coordinates. Unfortunately, the transformation tutorial doesn't seem to talk about it. So I came up with something analogous to the answer by wilywampa类似,但不知为何,有问题,我想不通:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch

t = [
    0, 6.297, 39.988, 46.288, 79.989, 86.298, 120.005, 126.314, 159.994,
    166.295, 200.012, 206.314, 240.005, 246.301, 280.05, 286.35, 320.032,
    326.336, 360.045, 366.345, 480.971, 493.146, 1080.117, 1093.154, 1681.019,
    1692.266, 2281.008, 2293.146, 2881.014, 2893.178, 3480.988, 3493.149,
    4080.077, 4092.298, 4681.007, 4693.275, 5281.003, 5293.183, 5881.023,
    5893.188, 6481.002, 6492.31
]
y = np.zeros(len(t))


fig, (axA, axB) = plt.subplots(2, 1)
fig.tight_layout()
for ax in (axA, axB):
    ax.set_frame_on(False)
    ax.axes.get_yaxis().set_visible(False)

axA.plot(t[:22], y[:22], c='black')
axA.plot(t[:22], y[:22], 'o', c='#ff4500')
axA.set_ylim((-0.05, 1))
axB.plot(t, y, c='black')
axB.plot(t, y, 'o', c='#ff4500')
axB.set_ylim((-0.05, 1))
pos1 = axB.get_position()
pos2 = [pos1.x0, pos1.y0 + 0.3, pos1.width, pos1.height]
axB.set_position(pos2)

trans = [
    # (ax.transAxes + ax.transData.inverted()).inverted().transform for ax in 
    (fig.transFigure + ax.transData.inverted()).inverted().transform for ax in
    (axA, axB)
]

con1 = ConnectionPatch(
    xyA=trans[0]((0, 0)), xyB=(0, 0.1), coordsA="figure fraction",
    coordsB="data", axesA=axA, axesB=axB, color="black"
)
con2 = ConnectionPatch(
    xyA=(500, 0), xyB=(500, 0.1), coordsA="data", coordsB="data",
    axesA=axA, axesB=axB, color="black"
)
print(trans[0]((0, 0)))
axB.add_artist(con1)
axB.add_artist(con2)
plt.show()

左边的线应该去上轴的(0, 0),但它没有。顺便说一句,如果我尝试转换为轴坐标,也会发生同样的情况,所以似乎存在根本性的错误。

我想使用图形坐标的原因是因为我实际上并不希望该行结束于 (0, 0),而是略低于“0”刻度标签。我不能在数据坐标中做到这一点,所以我试着换成数字坐标。

改编 this tutorial code 中的第二个示例,似乎不需要特殊的转换组合。如果 x 在数据坐标中,而 y 在图形坐标中,则可以使用 coordsA=axA.get_xaxis_transform(),。或者 coordsA=axA.transData 如果 xy 都在数据坐标中。请注意,当使用数据坐标时,您可以在视图外给出坐标 window;默认情况下 ConnectionPatch 不会被剪裁。

以下代码使用 z-order 将连接线放在其余部分的后面,并为 axA 的刻度标签添加半透明背景(避免文本被连接线划掉) :

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch

t = [0, 6.297, 39.988, 46.288, 79.989, 86.298, 120.005, 126.314, 159.994, 166.295, 200.012, 206.314, 240.005, 246.301, 280.05, 286.35, 320.032, 326.336, 360.045, 366.345, 480.971, 493.146, 1080.117, 1093.154, 1681.019, 1692.266, 2281.008, 2293.146, 2881.014, 2893.178, 3480.988, 3493.149, 4080.077, 4092.298, 4681.007, 4693.275, 5281.003, 5293.183, 5881.023, 5893.188, 6481.002, 6492.31]
y = np.zeros(len(t))

fig, (axA, axB) = plt.subplots(2, 1)
fig.tight_layout()

for ax in (axA, axB):
    ax.set_frame_on(False)
    ax.axes.get_yaxis().set_visible(False)

axA.plot(t[:22], y[:22], c='black')
axA.plot(t[:22], y[:22], 'o', c='#ff4500')
axA.set_ylim((-0.05, 1))
axB.plot(t, y, c='black')
axB.plot(t, y, 'o', c='#ff4500')
axB.set_ylim((-0.05, 1))
pos1 = axB.get_position()
pos2 = [pos1.x0, pos1.y0 + 0.3, pos1.width, pos1.height]
axB.set_position(pos2)

con1 = ConnectionPatch(xyA=(0, 0.02), coordsA=axA.get_xaxis_transform(),
                       xyB=(0, 0.05), coordsB=axB.get_xaxis_transform(),
                       # linestyle='--', color='black', zorder=-1)
                       linestyle='--', color='darkgrey', zorder=-1)
con2 = ConnectionPatch(xyA=(500, 0.02), coordsA=axA.get_xaxis_transform(),
                       xyB=(500, 0.05), coordsB=axB.get_xaxis_transform(),
                       linestyle='--', color='darkgrey', zorder=-1)
fig.add_artist(con1)
fig.add_artist(con2)

for lbl in axA.get_xticklabels():
    lbl.set_backgroundcolor((1, 1, 1, 0.8))
plt.show()