Matplotlib - 网格排列子图间距

发布于 2024-12-14 16:56:09 字数 803 浏览 2 评论 0原文

我正在尝试像时尚一样将一堆子图排列在网格中。问题在于,子图的数量随着用户选择绘制的数据而变化。现在我正在尝试以这种方式添加绘图:

    l = len(clicked)

    self.p=wx.Panel(self)
    self.dpi=100
    self.fig = Figure()
    self.canvas = FigCanvas(self.p, -1, self.fig)
    if l == 1:
        self.splt = self.fig.add_subplot(1,1,1)
        self.plt=self.splt.plot(np.arange(5),np.arange(5))
    else:
        for i in np.arange(l):
            self.splt=self.fig.add_subplot(l+1,2,i+1)
            self.fig.subplots_adjust(left=0.7, bottom=0.6, right=0.75, top=0.75)
            self.plt=self.splt.plot(np.arange(5),np.arange(5))

我只是使用假数据进行调试。无论如何,我正在使用 wxPython 在框架内绘制它。这里的clicked提供了用户所做选择的数量。我已经尝试过使用 subplots_adjust() ,结果与我想要的完全相反。情节被缩小得难以辨认。有没有办法将绘图排列在某种网格中。我看到有一个选项 subplot2grid,但我还没有让它处理可变数量的子图。

I am trying to arrange a bunch of subplots in a grid like fashion. The problem is that the number of subplots varies with user selection of what data to plot. Right now I am trying to add plots this way:

    l = len(clicked)

    self.p=wx.Panel(self)
    self.dpi=100
    self.fig = Figure()
    self.canvas = FigCanvas(self.p, -1, self.fig)
    if l == 1:
        self.splt = self.fig.add_subplot(1,1,1)
        self.plt=self.splt.plot(np.arange(5),np.arange(5))
    else:
        for i in np.arange(l):
            self.splt=self.fig.add_subplot(l+1,2,i+1)
            self.fig.subplots_adjust(left=0.7, bottom=0.6, right=0.75, top=0.75)
            self.plt=self.splt.plot(np.arange(5),np.arange(5))

I am just using fake data for debugging purposes. Anyhow, I am using wxPython to draw this inside a frame. clicked here provides the number of selections the user made. I already tried using subplots_adjust(), with quite the opposite result than I wanted. The plots are being shrunk something indiscernable. Is there a way to arrange teh plots in some sort of grid. I saw there is an option subplot2grid, but I havent gotten it to work with the variable number of subplots.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

糖粟与秋泊 2024-12-21 16:56:12

希望这会有所帮助:

from __future__ import division
import numpy as np
import pylab as plt

def divideSquare(N):
    if N<1:
        return 1,1

    minX = max(1,int(np.floor(np.sqrt(N))))
    maxX = max(minX+1, int(np.ceil(np.sqrt(5.0/3*N))))
    Nx = range(minX, maxX+1)
    Ny = [np.ceil(N/y) for y in Nx]
    err = [np.uint8(y*x - N) for y in Nx for x in Ny]
    ind = np.argmin(err)
    y = Nx[int(ind/len(Ny))]
    x = Ny[ind%len(Nx)]
    return min(y,x), max(y,x)

Nlist = np.arange(0,101)
empty = np.zeros_like(Nlist)
ratio = np.zeros_like(Nlist, dtype = float)
for k, N in enumerate(Nlist):
    y,x = divideSquare(N)
    empty[k] = y*x - N
    ratio[k] = 1.0 * x/y
    print y,x,y/x

plt.figure(1)
plt.clf()
y,x = divideSquare(2)
plt.subplot(y,x,1)    
plt.plot(Nlist, empty, 'k')
plt.xlabel('Number of plots')
plt.ylabel('Empty squares left')
plt.subplot(y,x,2)
plt.plot(Nlist, ratio, 'r')
plt.xlabel('Number of plots')
plt.ylabel('Ratio')

def divide2or3(N):
    if N<1:
        return 1,1
    if N%2==0:
        return int(np.ceil(N/2)), 2
    return int(np.ceil(N/3)), 3

Nlist = np.arange(0,101)
empty = np.zeros_like(Nlist)
ratio = np.zeros_like(Nlist, dtype = float)
for k, N in enumerate(Nlist):
    y,x = divide2or3(N)
    empty[k] = y*x - N
    ratio[k] = 1.0 * x/y
    print y,x,y/x

plt.figure(2)
plt.clf()
y,x = divide2or3(2)
plt.subplot(y,x,1)    
plt.plot(Nlist, empty, 'k')
plt.xlabel('Number of plots')
plt.ylabel('Empty squares left')
plt.subplot(y,x,2)
plt.plot(Nlist, ratio, 'r')
plt.xlabel('Number of plots')
plt.ylabel('Ratio')

plt.show()

divideSquare(N) 尝试获得接近 1 的比率,但空仓数量最少。
divide2or3(N) 为您提供 2 或 3 列的网格(如果反转 x 和 y,则为行),但我不确定这是否是您想要的 90 个图。

Hopefully this helps:

from __future__ import division
import numpy as np
import pylab as plt

def divideSquare(N):
    if N<1:
        return 1,1

    minX = max(1,int(np.floor(np.sqrt(N))))
    maxX = max(minX+1, int(np.ceil(np.sqrt(5.0/3*N))))
    Nx = range(minX, maxX+1)
    Ny = [np.ceil(N/y) for y in Nx]
    err = [np.uint8(y*x - N) for y in Nx for x in Ny]
    ind = np.argmin(err)
    y = Nx[int(ind/len(Ny))]
    x = Ny[ind%len(Nx)]
    return min(y,x), max(y,x)

Nlist = np.arange(0,101)
empty = np.zeros_like(Nlist)
ratio = np.zeros_like(Nlist, dtype = float)
for k, N in enumerate(Nlist):
    y,x = divideSquare(N)
    empty[k] = y*x - N
    ratio[k] = 1.0 * x/y
    print y,x,y/x

plt.figure(1)
plt.clf()
y,x = divideSquare(2)
plt.subplot(y,x,1)    
plt.plot(Nlist, empty, 'k')
plt.xlabel('Number of plots')
plt.ylabel('Empty squares left')
plt.subplot(y,x,2)
plt.plot(Nlist, ratio, 'r')
plt.xlabel('Number of plots')
plt.ylabel('Ratio')

def divide2or3(N):
    if N<1:
        return 1,1
    if N%2==0:
        return int(np.ceil(N/2)), 2
    return int(np.ceil(N/3)), 3

Nlist = np.arange(0,101)
empty = np.zeros_like(Nlist)
ratio = np.zeros_like(Nlist, dtype = float)
for k, N in enumerate(Nlist):
    y,x = divide2or3(N)
    empty[k] = y*x - N
    ratio[k] = 1.0 * x/y
    print y,x,y/x

plt.figure(2)
plt.clf()
y,x = divide2or3(2)
plt.subplot(y,x,1)    
plt.plot(Nlist, empty, 'k')
plt.xlabel('Number of plots')
plt.ylabel('Empty squares left')
plt.subplot(y,x,2)
plt.plot(Nlist, ratio, 'r')
plt.xlabel('Number of plots')
plt.ylabel('Ratio')

plt.show()

divideSquare(N) attempts to get a ratio close to 1 but with a minimal number of empty positions.
divide2or3(N) gives you a grid of 2 or 3 columns (or rows if you invert x and y), but I'm not sure if this is what you want for 90 plots.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文