在我使用fix, ax = plt.subplots(…)创建许多图形的脚本中,我得到警告RuntimeWarning:超过20个图形已被打开。通过pyplot接口(matplotlib.pyplot.figure)创建的图形将被保留,直到显式关闭,并且可能会消耗太多内存。
然而,我不明白为什么我会得到这个警告,因为在用fig.savefig(…)保存图形后,我用fig.clear()删除它;在我的代码中,我没有一次打开一个以上的数字。尽管如此,我还是得到了关于太多未公开数字的警告。这是什么意思/我怎样才能避免得到警告?
在您的图形对象上使用.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构造函数之后触发异常,也会发生这种情况。