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
    子图
  • 如果超过3行,则生成所需数量的行(每个行的大小为3)
  • 问题是,如果不避免代码重复,我无法做到这一点。以下是我编写的代码:

    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)