gpt4 book ai didi

python - 如何创建带有内部子图的网格图?

转载 作者:行者123 更新时间:2023-12-05 06:50:11 24 4
gpt4 key购买 nike

我已经配置了图 1 所示的 (5 x 1) 格式的子图,如 MWE 中的 Figure block A 所示。我试图将它们重复 n 次,以便它们以网格格式出现,其中行数和列数由函数 fitPlots 给出,如前所述 here ;给出如图2所示的输出。

enter image description here<强>图。 1 初始情节

enter image description here<强>图。 2 重复绘图(期望输出)

重复代码块以创建带有内部子图的网格图的最佳方法是什么? MWE 创建多个页面,我希望所有页面都在一个单页。

MWE

from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np
import math

x = np.arange(1, 100, 0.2)
y_a = np.sqrt(x)
y_b = np.sin(x)
y_c = np.sin(x)
y_d = np.cos(x) * np.cos(x)
y_e = 1/x


########## Figure block A #####################
with PdfPages('./plot_grid.pdf') as plot_grid_loop:
fig, (a, b, c, d, e) = plt.subplots(5, 1, sharex=True, gridspec_kw={'height_ratios': [5, 1, 1, 1, 1]})
a.plot(x, y_a)
b.plot(x, y_b)
c.plot(x, y_c)
d.plot(x, y_d)
e.plot(x, y_e)
plot_grid_loop.savefig()
plt.close
########## Figure block A #####################

# from https://stackoverflow.com/a/43366784/4576447
def fitPlots(N, aspect=(16,9)):
width = aspect[0]
height = aspect[1]
area = width*height*1.0
factor = (N/area)**(1/2.0)
cols = math.floor(width*factor)
rows = math.floor(height*factor)
rowFirst = width < height
while rows*cols < N:
if rowFirst:
rows += 1
else:
cols += 1
rowFirst = not(rowFirst)
return rows, cols


n_plots = 15

n_rows, n_cols = fitPlots(n_plots)

with PdfPages('./plot_grid.pdf') as plot_grid_loop:
for m in range(1, n_plots+1):
fig, (a, b, c, d, e) = plt.subplots(5, 1, sharex=True, gridspec_kw={'height_ratios': [5, 1, 1, 1, 1]})
a.plot(x, y_a)
b.plot(x, y_b)
c.plot(x, y_c)
d.plot(x, y_d)
e.plot(x, y_e)
plot_grid_loop.savefig()
plt.close

最佳答案

这可以通过使用 gs_fig = fig.add_gridspec() 生成一个 GridSpec 对象来完成。包含足够的行和列以适合五个图形 block (请注意,当您使用 plt.subplots 时,还会生成一个 GridSpec,并且可以使用 ax.get_gridspec() 访问).然后可以用 gs_sub = gs_fig[i].subgridspec() 的子 GridSpec 填充 GridSpec 中的每个空槽。保存五个子图。棘手的部分是共享 x 轴。这可以通过生成一个空的第一个 Axes 来完成,所有子图的 x 轴可以与之共享。

以下示例仅使用三个图形 block 来说明这一点,基于您共享的代码示例,但在图形设计方面存在一些差异:行数是根据所选的列数计算的,图形尺寸是根据选定的图形宽度和纵横比设置。不包括将图形保存到pdf文件的代码。

import numpy as np               # v 1.19.2
import matplotlib.pyplot as plt # v 3.3.4

# Create variables to plot
x = np.arange(1, 100, 0.2)
y_a = np.sqrt(x)
y_b = np.sin(x)
y_c = np.sin(x)
y_d = np.cos(x)*np.cos(x)
y_e = 1/x

# Set parameters for figure dimensions
nplots = 3 # random number of plots for this example
ncols = 2
nrows = int(np.ceil(nplots/ncols))
subp_w = 10/ncols # 10 is the total figure width in inches
subp_h = 1*subp_w # set subplot aspect ratio

# Create figure containing GridSpec object with appropriate dimensions
fig = plt.figure(figsize=(ncols*subp_w, nrows*subp_h))
gs_fig = fig.add_gridspec(nrows, ncols)

# Loop through GridSpec to add sub-GridSpec for each figure block
heights = [5, 1, 1, 1, 1]
for i in range(nplots):
gs_sub = gs_fig[i].subgridspec(len(heights), 1, height_ratios=heights, hspace=0.2)
ax = fig.add_subplot(gs_sub[0, 0]) # generate first empty Axes to enable sharex
ax.axis('off') # remove x and y axes because it is overwritten in the loop below
# Loop through y variables to plot all the subplots with shared x-axis
for j, y in enumerate([y_a, y_b, y_c, y_d, y_e]):
ax = fig.add_subplot(gs_sub[j, 0], sharex=ax)
ax.plot(x, y)
if not ax.is_last_row():
ax.tick_params(labelbottom=False)

subgridspec


引用:matplotlib tutorial GridSpec using SubplotSpec

关于python - 如何创建带有内部子图的网格图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66468158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com