Python 在matplotlib中,使用显示坐标从轴坐标到绝对地物坐标的转换不起作用

Python 在matplotlib中,使用显示坐标从轴坐标到绝对地物坐标的转换不起作用,python,matplotlib,transformation,Python,Matplotlib,Transformation,我需要在Matplotlib中沿y轴在边上绘制点标记。我希望标记在x方向的位置是恒定的(独立于轴的大小),而y方向应该在数据坐标中。我曾尝试根据创建混合转换,但它没有按照我的期望工作。谁能解释一下我犯了什么错误?如何修复它 import matplotlib print(matplotlib.__version__) # 3.3.1 import matplotlib.transforms as transforms fig, ax = plt.subplots(figsize=(2, 3.5

我需要在Matplotlib中沿y轴在边上绘制点标记。我希望标记在x方向的位置是恒定的(独立于轴的大小),而y方向应该在数据坐标中。我曾尝试根据创建混合转换,但它没有按照我的期望工作。谁能解释一下我犯了什么错误?如何修复它

import matplotlib
print(matplotlib.__version__) # 3.3.1

import matplotlib.transforms as transforms
fig, ax = plt.subplots(figsize=(2, 3.5))
ax.set_xlim((0,2))
ax.set_ylim((0,2))
ax.plot([0,2], [0,2])
ax.grid(True)
fig.set_facecolor('lightgray')
point = [1,0]

# Ok, let's use the y-axis transform to plot in axis coordinates in the x-direction
t_yaxis = ax.get_yaxis_transform()
ax.scatter([1, 1.1], [2, 2], transform=t_yaxis, clip_on=False, label='p1')
# This works but the distance between points depends on the size of the axes. 
# We want to set it in absolute units.

# Here we create blended transformation which actually works exactly the same as the previous one.
t_own_yaxis = transforms.blended_transform_factory(ax.transAxes, ax.transData)
ax.scatter([1, 1.1], [1.5, 1.5], transform=t_own_yaxis, clip_on=False, label='p2')

# Let's try to blend physical coordinates of the figure in x-direction 
# with data coordinates in y-direction.
t_blended = transforms.blended_transform_factory(fig.dpi_scale_trans, ax.transData)
ax.scatter([1, 1.1], [1, 1], transform=t_blended, clip_on=False, label='p3')
# This works for distance between points but we want to offset the points at the edge of the axes
# asi in previous cases.

# Let's calculate the location of the edge and plot using that.
t_yaxis2blended = t_yaxis + t_blended.inverted()
p4 = t_yaxis2blended.transform([1, 0.5])
print(p4)
ax.scatter([p4[0], p4[0]+0.1], [0.5, 0.5], transform=t_blended, clip_on=False, label='p4')
# Why the left 'p4' point is not at the edge?

plt.legend()


[编辑]蓝色、橙色和绿色的圆点是我所期望的。我预计左边的红点是[2.0,0.5]

有趣的是,如果我使用交互式后端
%matplotlib notebook
渲染绘图,结果与预期一致:

[编辑]我需要这样做的原因是对树状图进行注释,如下所示:

可以使用轴比例,并根据轴尺寸计算点之间的绝对距离:

import matplotlib.pyplot as plt
import matplotlib.transforms as transforms
fig, ax = plt.subplots(figsize=(2, 3.5))
ax.set_xlim((0,2))
ax.set_ylim((0,2))
ax.plot([0,2], [0,2])
ax.grid(True)
fig.set_facecolor('lightgray')

t_yaxis = ax.get_yaxis_transform()
ax.scatter([1, 1.1], [2, 2], transform=t_yaxis, clip_on=False, label='p1')

bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
shift = 0.1 / bbox.width
ax.scatter([1, 1 + shift], [0, 0], transform=t_yaxis, clip_on=False, label='p5')

plt.legend()

如果您想抵消某些内容,可以使用
缩放转换

导入matplotlib.pyplot作为plt
将matplotlib.transforms作为转换导入
图,ax=plt.子批次(图尺寸=(2,3.5))
ax.set_xlim((0,2))
ax.set_ylim((0,2))
ax.图([0,2],[0,2])
t_yaxis=ax.get_yaxis_transform()
ax.scatter([1],[2],transform=t\u yaxis,clip\u on=False,label='p1')
#水平偏移-0.25英寸
trans=t_yaxis+变换。缩放翻译(-0.25,0,图dpi_scale_trans)
ax.scatter([1],[2],transform=trans,clip\u on=False,label='p1')
plt.show()

这将使第二个(橙色)点始终与蓝色偏移-0.25英寸,无论窗口大小如何(注意上图已手动调整大小)


更多细节见

橙色和蓝色圆点是我根据您使用的变换预期的位置。您希望它们位于何处?我希望左侧的红点位于[2.0,0.5]。在这个答案中,建议调用
plt.draw()
。我已经测试过了。还有一个建议是“通过图形坐标连接事物”。这看起来很有趣,但我不知道怎么做。好吧,很公平。只要你不相信,那是正确的;不要改变体型大小。如果使用
%matplotlib inline
的问题是,它通过调用
fig.savefig('repr.png',bbox_inches='tight')
为您调整图形大小。这个故事的寓意是不要使用
dpi\u scale\u trans
,除非你真的想要绝对英寸的东西,而不管数字大小。@JodyKlymak我编辑了这个问题,让我的意图更清楚。我只想在轴的右边缘绘制点,其水平间距与图/轴的大小无关。也许
ScaledTranslation
是另一种方法。