warning about too many open figures

后端 未结 6 1894
陌清茗
陌清茗 2020-11-29 15:38

In a script where I create many figures with fix, ax = plt.subplots(...), I get the warning RuntimeWarning: More than 20 figures have been opened. Figures c

6条回答
  •  一生所求
    2020-11-29 16:13

    Here's a bit more detail to expand on Hooked's answer. When I first read that answer, I missed the instruction to call clf() instead of creating a new figure. clf() on its own doesn't help if you then go and create another figure.

    Here's a trivial example that causes the warning:

    from matplotlib import pyplot as plt, patches
    import os
    
    
    def main():
        path = 'figures'
        for i in range(21):
            _fig, ax = plt.subplots()
            x = range(3*i)
            y = [n*n for n in x]
            ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
            plt.step(x, y, linewidth=2, where='mid')
            figname = 'fig_{}.png'.format(i)
            dest = os.path.join(path, figname)
            plt.savefig(dest)  # write image to file
            plt.clf()
        print('Done.')
    
    main()
    

    To avoid the warning, I have to pull the call to subplots() outside the loop. In order to keep seeing the rectangles, I need to switch clf() to cla(). That clears the axis without removing the axis itself.

    from matplotlib import pyplot as plt, patches
    import os
    
    
    def main():
        path = 'figures'
        _fig, ax = plt.subplots()
        for i in range(21):
            x = range(3*i)
            y = [n*n for n in x]
            ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
            plt.step(x, y, linewidth=2, where='mid')
            figname = 'fig_{}.png'.format(i)
            dest = os.path.join(path, figname)
            plt.savefig(dest)  # write image to file
            plt.cla()
        print('Done.')
    
    main()
    

    If you're generating plots in batches, you might have to use both cla() and close(). I ran into a problem where a batch could have more than 20 plots without complaining, but it would complain after 20 batches. I fixed that by using cla() after each plot, and close() after each batch.

    from matplotlib import pyplot as plt, patches
    import os
    
    
    def main():
        for i in range(21):
            print('Batch {}'.format(i))
            make_plots('figures')
        print('Done.')
    
    
    def make_plots(path):
        fig, ax = plt.subplots()
        for i in range(21):
            x = range(3 * i)
            y = [n * n for n in x]
            ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
            plt.step(x, y, linewidth=2, where='mid')
            figname = 'fig_{}.png'.format(i)
            dest = os.path.join(path, figname)
            plt.savefig(dest)  # write image to file
            plt.cla()
        plt.close(fig)
    
    
    main()
    

    I measured the performance to see if it was worth reusing the figure within a batch, and this little sample program slowed from 41s to 49s (20% slower) when I just called close() after every plot.

提交回复
热议问题