在我使用fix, ax = plt.subplots(…)创建许多图形的脚本中,我得到警告RuntimeWarning:超过20个图形已被打开。通过pyplot接口(matplotlib.pyplot.figure)创建的图形将被保留,直到显式关闭,并且可能会消耗太多内存。

然而,我不明白为什么我会得到这个警告,因为在用fig.savefig(…)保存图形后,我用fig.clear()删除它;在我的代码中,我没有一次打开一个以上的数字。尽管如此,我还是得到了关于太多未公开数字的警告。这是什么意思/我怎样才能避免得到警告?


当前回答

import matplotlib.pyplot as plt  
plt.rcParams.update({'figure.max_open_warning': 0})

如果使用这个,就不会得到错误,这是最简单的方法。

其他回答

如果您有意在内存中保留许多图,但不想收到警告,则可以在生成图形之前更新选项。

import matplotlib.pyplot as plt
plt.rcParams.update({'figure.max_open_warning': 0})

这将防止在不改变内存管理方式的情况下发出警告。

matplotlib by default keeps a reference of all the figures created through pyplot. If a single variable used for storing matplotlib figure (e.g "fig") is modified and rewritten without clearing the figure, all the plots are retained in RAM memory. Its important to use plt.cla() and plt.clf() instead of modifying and reusing the fig variable. If you are plotting thousands of different plots and saving them without clearing the figure, then eventually your RAM will get exhausted and program will get terminated. Clearing the axes and figures have a significant impact on memory usage if you are plotting many figures. You can monitor your RAM consumption in task manager (Windows) or in system monitor (Linux). First your RAM will get exhausted, then the OS starts consuming SWAP memory. Once both are exhausted, the program will get automatically terminated. Its better to clear figures, axes and close them if they are not required.

在您的图形对象上使用.clf或.cla,而不是创建一个新的图形。从@DavidZwicker

假设您已经导入pyplot为

import matplotlib.pyplot as plt

Plt.cla()清除一个轴,即当前图中的当前活动轴。它不影响其他轴。

Plt.clf()清除整个当前图形及其所有轴,但保持窗口打开,以便其他图形可以重用它。

Plt.close()关闭一个窗口,如果没有指定的话,该窗口将是当前窗口。Plt.close ('all')将关闭所有打开的数字。

del fig不起作用的原因是pyplot状态机保留了对周围图形的引用(如果它想知道“当前图形”是什么,就必须这样做)。这意味着即使您删除了对图的引用,也至少有一个活动的引用,因此它永远不会被垃圾收集。

由于我在这里对这个答案进行了集体智慧的投票,@JoeKington在评论中提到,plt.close(图)将从pylab状态机(plt._pylab_helpers.Gcf)中删除一个特定的图形实例,并允许它被垃圾收集。

下面的代码片段为我解决了这个问题:


class FigureWrapper(object):
    '''Frees underlying figure when it goes out of scope. 
    '''

    def __init__(self, figure):
        self._figure = figure

    def __del__(self):
        plt.close(self._figure)
        print("Figure removed")


# .....
    f, ax = plt.subplots(1, figsize=(20, 20))
    _wrapped_figure = FigureWrapper(f)

    ax.plot(...
    plt.savefig(...
# .....

当_wrapped_figure超出作用域时,运行时调用我们的__del__()方法,其中包含plt.close()。即使在_wrapped_figure构造函数之后触发异常,也会发生这种情况。

import matplotlib.pyplot as plt  
plt.rcParams.update({'figure.max_open_warning': 0})

如果使用这个,就不会得到错误,这是最简单的方法。