轴 ('square' ) 和 set_xlim 之间的 python 相互作用

标签 python matplotlib

对于相关图,我希望有一个光学正方形图(x 和 y 的像素长度相同),但 x 和 y 也有一定的轴限制。我可以分别获取这两个,但不能同时获取:

import matplotlib.pyplot as plt

f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]

ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')

myXlim = [0, 8]
ax1.set_xlim(myXlim)
ax2.set_xlim(myXlim)

ax1.axis('square')
ax2.axis('square')
# limit is gone here

ax1.set_xlim(myXlim)
ax2.set_xlim(myXlim)
# square is gone here

plt.show()

如果我只使用 ax1.set_xlim(myXlim) (而不是 square),那么我可以手动调整窗口大小以获得我想要的,但我怎样才能自动执行此操作?

最佳答案

获取正方形子图的一个选项是设置子图参数,以便生成的子图自动调整为正方形。这有点复杂,因为需要考虑所有边距和间距。

import matplotlib.pyplot as plt

f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]

def square_subplots(fig):
    rows, cols = ax1.get_subplotspec().get_gridspec().get_geometry()
    l = fig.subplotpars.left
    r = fig.subplotpars.right
    t = fig.subplotpars.top
    b = fig.subplotpars.bottom
    wspace = fig.subplotpars.wspace
    hspace = fig.subplotpars.hspace
    figw,figh = fig.get_size_inches()

    axw = figw*(r-l)/(cols+(cols-1)*wspace)
    axh = figh*(t-b)/(rows+(rows-1)*hspace)
    axs = min(axw,axh)
    w = (1-axs/figw*(cols+(cols-1)*wspace))/2.
    h = (1-axs/figh*(rows+(rows-1)*hspace))/2.
    fig.subplots_adjust(bottom=h, top=1-h, left=w, right=1-w)

ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')

#f.tight_layout() # optionally call tight_layout first
square_subplots(f)

plt.show()

这里的好处是能够自由缩放和自动缩放。缺点是一旦图形尺寸发生变化,子图尺寸就不再是方形的。为了克服这个缺点,可以另外注册图形大小变化的回调。

import matplotlib.pyplot as plt

f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]

class SquareSubplots():
    def __init__(self, fig):
        self.fig = fig
        self.ax = self.fig.axes[0]
        self.figw,self.figh = 0,0
        self.params = [self.fig.subplotpars.left,
                       self.fig.subplotpars.right,
                       self.fig.subplotpars.top,
                       self.fig.subplotpars.bottom,
                       self.fig.subplotpars.wspace,
                       self.fig.subplotpars.hspace]
        self.rows, self.cols = self.ax.get_subplotspec().get_gridspec().get_geometry()
        self.update(None)
        self.cid = self.fig.canvas.mpl_connect('resize_event', self.update)


    def update(self, evt):
        figw,figh = self.fig.get_size_inches()
        if self.figw != figw or self.figh != figh:
            self.figw = figw; self.figh = figh
            l,r,t,b,wspace,hspace = self.params
            axw = figw*(r-l)/(self.cols+(self.cols-1)*wspace)
            axh = figh*(t-b)/(self.rows+(self.rows-1)*hspace)
            axs = min(axw,axh)
            w = (1-axs/figw*(self.cols+(self.cols-1)*wspace))/2.
            h = (1-axs/figh*(self.rows+(self.rows-1)*hspace))/2.
            self.fig.subplots_adjust(bottom=h, top=1-h, left=w, right=1-w)
            self.fig.canvas.draw_idle()

s = SquareSubplots(f)

ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')

plt.show()

上述解决方案的工作原理是限制子图在其网格内部的空间。相反的方法,即子图的大小以某种方式固定,将显示在 Create equal aspect (square) plot with multiple axes when data limits are different? 的答案中。 .

关于轴 ('square' ) 和 set_xlim 之间的 python 相互作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51474842/

相关文章:

python - 如何选择合适的 Python 解析器生成器来解析 C 结构体定义?

python - matplotlib 将 x 轴上的刻度线命名为 1、2、4、8、16 等

python - 如何在单独的数据帧之间合并和分组

python - Pylab/Matplotlib 将多个饼图合并为一个 PDF

python - 使用 MatPlotLib 绘制点周围误差范围的折线图

python - 迭代不同长度的列表

python - 在自定义数据上训练 EAST 文本检测器

python - Matplotlib - 绘制非均匀线分布

python - 设置 yticks 颜色以匹配条形图颜色 python

python - 可以在 matplotlib 的不同图中保持相同颜色的相同线条吗?