You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何判断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

火山引擎 最新活动