【问题标题】:Remove the extra plot in the matplotlib subplot删除 matplotlib 子图中的多余图
【发布时间】:2017-12-12 08:02:44
【问题描述】:

我想以 2 x 3 设置(即 2 行和 3 列)绘制 5 个数据框。这是我的代码:但是在第 6 个位置(第二行和第三列)有一个额外的空图,我想摆脱它。我想知道如何删除它,以便第一行有三个地块,第二行有两个地块。

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=3)

fig.set_figheight(8)
fig.set_figwidth(15)



df[2].plot(kind='bar',ax=axes[0,0]); axes[0,0].set_title('2')

df[4].plot(kind='bar',ax=axes[0,1]); axes[0,1].set_title('4')

df[6].plot(kind='bar',ax=axes[0,2]); axes[0,2].set_title('6')

df[8].plot(kind='bar',ax=axes[1,0]); axes[1,0].set_title('8')

df[10].plot(kind='bar',ax=axes[1,1]); axes[1,1].set_title('10')

plt.setp(axes, xticks=np.arange(len(observations)), xticklabels=map(str,observations),
        yticks=[0,1])

fig.tight_layout()

【问题讨论】:

    标签: python matplotlib subplot


    【解决方案1】:

    以前的解决方案不适用于sharex=True。如果你有,请考虑下面的解决方案,它也处理二维子图布局。

    import matplotlib.pyplot as plt
    
    
    columns = ["a", "b", "c", "d"]
    fig, axes = plt.subplots(4,1, sharex=True)
    
    
    plotted = {}
    for c, ax in zip(columns, axes.ravel()):
        plotted[ax] = 0
        if c == "d":
            print("I didn't actually need 'd'")
            continue
        ax.plot([1,2,3,4,5,6,5,4,6,7])
        ax.set_title(c)
        plotted[ax] = 1
    
    if axes.ndim == 2:
        for a, axs in enumerate(reversed(axes)):
            for b, ax in enumerate(reversed(axs)):
                if plotted[ax] == 0:
                    # one can use get_lines(), get_images(), findobj() for the propose
                    ax.set_axis_off()
                    # now find the plot above
                    axes[-2-a][-1-b].xaxis.set_tick_params(which='both', labelbottom=True)
                else:
                    break # usually only the last few plots are empty, but delete this line if not the case
    else:
        for i, ax in enumerate(reversed(axes)):
            if plotted[ax] == 0:
                ax.set_axis_off()
                axes[-2-i].xaxis.set_tick_params(which='both', labelbottom=True)
                # should also work with horizontal subplots
                # all modifications to the tick params should happen after this
            else:
                break
    
    plt.show()
    

    二维fig, axes = plot.subplots(2,2, sharex=True)

    【讨论】:

      【解决方案2】:

      关闭所有轴,并仅在您在它们上绘图时将它们一个接一个地打开。那么你就不需要提前知道索引了,例如:

      import matplotlib.pyplot as plt
      
      columns = ["a", "b", "c", "d"]
      fig, axes = plt.subplots(nrows=len(columns))
      
      for ax in axes:
          ax.set_axis_off()
      
      for c, ax in zip(columns, axes):
          if c == "d":
              print("I didn't actually need 'd'")
              continue
      
          ax.set_axis_on()
          ax.set_title(c)
      
      plt.tight_layout()
      plt.show()
      

      【讨论】:

      • +1 因为当我编写一般的绘图例程并且不知道会有多少子图时,它效果最好。所有其他答案都是严格正确的w.r.t。 OP的问题,但这更通用。
      • -1 因为如果您在 subplots 调用中添加 sharex=True 它将不起作用。 Nether 用于其他解决方案,例如 delaxesset_axis_off
      【解决方案3】:

      试试这个:

      fig.delaxes(axes[1][2])
      

      创建子图的更灵活的方法是fig.add_axes() 方法。参数是一个矩形坐标列表:fig.add_axes([x, y, xsize, ysize])。这些值与画布大小相关,因此0.5xsize 表示子图的宽度为窗口的一半。

      【讨论】:

      • 谢谢。有效。你知道如何将两个地块移到中心吗?
      • 如果你想要一个不同于常规网格的子图布局,通常使用fig.add_axes() 方法更容易。它采用矩形的坐标(作为列表)并返回单个坐标区对象。坐标是相对于窗口大小的。我会在我的回答中举个例子。
      • 使用add_axes 既不是很好也不推荐的生成子图的方法。 plt.subplotsGridspec 都是可行的方法,delaxesax.axis("off") 可用于删除或隐藏子图。
      • 您能解释一下原因吗?我知道在大多数情况下plt.subplots 就足够了,然后是推荐的方式。但在这种情况下,或者如果你想要重叠的子图,我认为这是要走的路。
      • 嗨 Johannes,如果我这样定义我的坐标轴会怎样:f, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8)) = plt .subplots(4, 2, sharex=True, sharey=True, figsize=(10,20)) 而我不需要我的 ax8?
      【解决方案4】:

      如果您知道要删除哪个图,您可以像这样给出索引并删除:

      axes.flat[-1].set_visible(False) # to remove last plot
      

      【讨论】:

        【解决方案5】:

        或者,使用axes方法set_axis_off()

        axes[1,2].set_axis_off()
        

        【讨论】:

        • 当我提前不知道行数/列数时,我发现这比@Johannes 的建议更容易实现
        • 我似乎无法在第一行绘图中完成这项工作,即axes[0,2].set_axis_off()。它抛出一个IndexError: too many indices for array。子图是 1 行 4 列。关于如何在第一行实现这一点的任何指示?
        • 在您的情况下,轴不再是二维网格,而是子图对象的一维数组。所以你需要设置axes[2].set_axis_off()
        猜你喜欢
        • 1970-01-01
        • 2018-03-24
        • 2020-06-20
        • 2020-07-23
        • 1970-01-01
        • 2012-10-11
        • 1970-01-01
        相关资源
        最近更新 更多