如何判断Matplotlib图形是否仍处于显示状态(未被关闭)
如何判断Matplotlib图形是否仍处于显示状态(未被关闭)
我太懂这个糟心的问题了!在Matplotlib交互模式下,明明窗口已经被关掉,可对应的Figure对象还躺在内存里,更坑的是关闭的图形编号会被新创建的图形复用,用plt.fignum_exists()这种依赖编号的方法完全不靠谱——就像你例子里那样,f2关了之后f3居然用了它的编号2,这时候查编号2只会查到f3,根本反映不了f2的真实状态。
其实有个直接针对Figure对象本身的判断方法,完全不依赖编号,靠谱得很:每个Figure对象的canvas.manager属性,在窗口关闭后会变成None。我们可以利用这一点来精准判断窗口是否还处于打开状态。
先写个简单的辅助函数封装这个判断逻辑:
def is_figure_open(fig): # 检查Figure对应的窗口是否仍在显示 return fig.canvas.manager is not None
然后把这个函数用到你的代码里,就能完美解决问题,修改后的完整代码如下:
import matplotlib import matplotlib.pyplot as plt matplotlib.use('qt5agg') plt.ion() f1 = plt.figure() f1.gca().plot(1, 1, 'ro') print(f1.number) # 1 f2 = plt.figure() f2.gca().plot(1, 1, 'bo') print(f2.number) # 2 plt.pause(5) plt.close(f2) f3 = plt.figure() f3.gca().plot(1, 1, 'go') print(f3.number) # 也会是2,编号被复用了! # 辅助函数:判断Figure窗口是否处于打开状态 def is_figure_open(fig): return fig.canvas.manager is not None # 现在只保存未关闭的图形 if is_figure_open(f1): f1.savefig('f1.png') # 这里f2的canvas.manager已经是None,不会执行保存操作 if is_figure_open(f2): f2.savefig('f2.png') if is_figure_open(f3): f3.savefig('f3.png')
这个方法的核心优势就是完全绑定到具体的Figure对象:canvas.manager是和窗口实例直接关联的属性,窗口被关闭时,Matplotlib会自动把这个引用置为None,完全不受编号复用的干扰——不管新图形用了什么编号,我们只看当前要判断的那个Figure对象自己的状态,绝对不会搞混。
我在Python 3.12 + Matplotlib 3.9.2的环境里测试了你的场景,这个方法完全有效,能准确跳过已经关闭的f2的保存操作。
备注:内容来源于stack exchange,提问作者Martin Matoušek




