set_aspect() 和 matplotlib 中的坐标变换

set_aspect() and coordinate transforms in matplotlib

我 运行 尝试在子图之间画一条线时,似乎是 matplotlib(版本 1.4.3)/pyplot 中的错误:设置 set_aspect("equal") 后,出现相关坐标变换函数(transData)不更新。执行下面的代码,取消注释 ax.set_aspect("equal") 以查看差异。

import matplotlib.pyplot as plt
import matplotlib as mpl    

f, (ax1, ax2) = plt.subplots(1, 2, sharey='all', sharex='all')

for ax in (ax1, ax2):
    # ax.set_aspect("equal")
    ax.set_ylim([-.2, 1.2])
    ax.set_xlim([-.2, 1.2])        

# From 

transFigure = f.transFigure.inverted()

coord1 = transFigure.transform(ax1.transData.transform([0,0]))
coord2 = transFigure.transform(ax2.transData.transform([1,0]))

line = mpl.lines.Line2D((coord1[0],coord2[0]),(coord1[1],coord2[1]),
                    transform=f.transFigure)
f.lines.append(line)

plt.show()

相关图片在这里 (1) and here (2)。

您遇到的问题是 set_aspect 直到绘制操作后才应用。因此,当您制作线路时,限制没有改变。请注意第二张图片中的不同 x 限制,而线条位于同一位置:绘制线条时 x 限制没有改变,因为它们尚未更改,并且直到 plt.show()。解决方案是在执行 set_aspect 之后但在开始处理转换之前添加 plt.draw()。下面的代码就是这样做的,打印语句明确了不同时间的限制和转换问题:

import matplotlib.pyplot as plt
import matplotlib as mpl    

f, (ax1, ax2) = plt.subplots(1, 2, sharey='all', sharex='all')

for ax in (ax1, ax2):
    ax.set_ylim([-.2, 1.2])
    ax.set_xlim([-0.2, 1.2])  

transFigure = f.transFigure.inverted()

print ax1.get_xlim(), ax1.transData.transform([0,0])

for ax in (ax1, ax2):
    ax.set_aspect('equal')

print ax1.get_xlim(), ax1.transData.transform([0,0])

plt.draw()

print ax1.get_xlim(), ax1.transData.transform([0,0])

coord1 = transFigure.transform(ax1.transData.transform([0,0]))
coord2 = transFigure.transform(ax2.transData.transform([1,0]))

line = mpl.lines.Line2D((coord1[0],coord2[0]),(coord1[1],coord2[1]),
                    transform=f.transFigure)
f.lines.append(line)

plt.show()

这一点确实应该添加到 set_aspect 的文档字符串中,我会看看是否可以做到这一点。这不是错误:在准备好绘制情节之前,无法真正确定方面。

cge 对 为什么 的评估是正确的,但对我来说,他的代码产生了:

x 限制变得混乱,因为它们应该与 y 限制匹配并且 相等。

要解决此问题,您可以使用子图的 figsize 关键字参数将图形大小调整为更合适的大小。在下面的代码中,我选择了 10in x 5in.

import matplotlib.pyplot as plt
import matplotlib as mpl

f, (ax1, ax2) = plt.subplots(1, 2, sharey='all', sharex='all', figsize=(10,5))

for ax in (ax1, ax2):
    ax.set_aspect("equal")
    ax.set_ylim([-.2, 1.2])
    ax.set_xlim([-.2, 1.2])

plt.draw()


# From 
transFigure = f.transFigure.inverted()

coord1 = transFigure.transform(ax1.transData.transform([0,0]))
coord2 = transFigure.transform(ax2.transData.transform([1,0]))

line = mpl.lines.Line2D(
                    (coord1[0],coord2[0]),
                    (coord1[1],coord2[1]),
                    transform=f.transFigure)
f.lines.append(line)

plt.show()

这会产生: