Python 动态大小的子段代码重复:如何解决?
我试图保存一张由几个子图组成的图片:问题是,最初我不知道需要多少子图(取决于Python 动态大小的子段代码重复:如何解决?,python,matplotlib,subplot,Python,Matplotlib,Subplot,我试图保存一张由几个子图组成的图片:问题是,最初我不知道需要多少子图(取决于num_plots),因此我想获得一个函数,该函数在不同情况下生成不同的图: 如果num\u plots小于等于3,则精确地创建一行num\u plots子图 如果超过3行,则生成所需数量的行(每个行的大小为3) 问题是,如果不避免代码重复,我无法做到这一点。以下是我编写的代码: def foo(num_plots, ...): # ... obtain data to plot ('all_results')
num_plots
),因此我想获得一个函数,该函数在不同情况下生成不同的图:
num\u plots
小于等于3,则精确地创建一行num\u plots
子图def foo(num_plots, ...):
# ... obtain data to plot ('all_results')
total_cols = 3 if num_plots > 2 else num_plots
total_rows = math.ceil(num_plots / total_cols)
fig, axs = plt.subplots(nrows=total_rows, ncols=total_cols, figsize=(7 * total_cols, 7 * total_rows),
constrained_layout=True)
for i in range(num_plots):
row = i // total_cols
pos = i % total_cols
# psi_name and psi_value depend on the parameters of the function
if num_plots == 1:
sns.kdeplot(all_results[:, i], color='magenta', ax=axs)
axs.hist(all_results[:, i], bins=nbins)
axs.axvline(x=psi_value, linestyle='--', color='red')
axs.set_title(f"Estimation test for {psi_name} = {psi_value}")
elif total_rows == 1:
sns.kdeplot(all_results[:, i], color='magenta', ax=axs[pos])
axs[pos].hist(all_results[:, i], bins=nbins)
axs[pos].axvline(x=psi_value, linestyle='--', color='red')
axs[pos].set_title(f"Estimation test for {psi_name} = {psi_value}")
else:
sns.kdeplot(all_results[:, i], color='magenta', ax=axs[row, pos])
axs[row, pos].hist(all_results[:, i], bins=nbins)
axs[row, pos].axvline(x=psi_value, linestyle='--', color='red')
axs[row, pos].set_title(f"Estimation test for {psi_name} = {psi_value}")
plt.savefig(token_hex(8))
正如您所看到的,问题是根据需要的绘图数量,我必须使用axs
或axs[pos]
或axs[row,pos]
。请注意,只需使用axs[row,pos]
就会出现错误如何解决此代码重复问题?
以下是由该函数生成的图的几个示例:
如果num\u plots
为1:
如果num_plots
为3:
如果num_plots
为4:
顺序绘图技术是否适用于您的目的?但是,它被设置为在一个图表上绘制多个图表,因此单个图表的大小将使其最大化。您将收到警告,但可以忽略它
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(12,9))
x = np.linspace(-3, 3, 20)
cnt = 5
cols = 3
rows = round(cnt / cols,0)
for i in range(cnt):
ax = fig.add_subplot(rows,cols,i+1)
ax.plot(x, x**i)
如果希望约束布局工作,可以创建gridspec并逐段添加:
导入matplotlib.pyplot作为plt
将numpy作为np导入
图=plt.图(figsize=(12,9),约束布局=真)
x=np.linspace(-3,3,20)
cnt=5
cols=3
行=圆形(cnt/cols,0)
gs=图添加网格规格(int(行),int(列))
对于范围内的ind(cnt):
i=内部(np.楼层(独立/cols))
j=ind%cols
ax=图添加子批次(gs[i,j])
ax.绘图(x,x**ind)
plt.show()
请注意,上面使用的未来matplotlib 3.4,
添加子批次
也可以用于受约束的布局,但尚未发布:谢谢,这就是我要找的!另一个小问题:如果我尝试使用constrated_layout=True
它们太近(重叠轴标签),则结果图对我来说有点太远。你能不能给我一个不夸张地接近阵型的方法?提前谢谢constrated_layout=False
如果我解锁它会发生什么?如果有改进,试试这个。fig.subplots\u adjust(wspace=0.2,hspace=0.2)