You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

plt.show()仅调用2次却生成3张图,其中1张秒关的技术问题

问题分析与解决

问题现象

仅在两个脚本中各调用1次plt.show()(共2次),但实际生成3张图,其中1张会在1秒左右自动关闭。

代码片段

from ScriptsTogather import new
import matplotlib.pyplot as plt
import multiprocessing

fig, axes = plt.subplots(2, 1, figsize=(4, 4), num='pyplot')
plt.show(block=False)

def process_msg(msg):
         fig.canvas.  # 原代码此处不完整,推测为画布更新操作
         fig.canvas.flush_events()

def read_mindray():
    # 读取数据的逻辑
    pass

def read():
    # 子进程目标函数,原代码未给出完整实现
    pass

if __name__ == "__main__":
    try: 
        thread_mindray = multiprocessing.Process(target=read, daemon=True)
        thread_mindray.start()
        new()
    except:
        raise Exception
        print('end?')

原因解析

  1. 多进程上下文继承:用multiprocessing.Process创建子进程时,子进程会继承主进程的matplotlib上下文(包括已创建的fig对象)。如果子进程中触发了任何绘图相关操作(哪怕是导入模块时的隐式调用),就会额外生成一个窗口。子进程作为守护进程退出后,这个窗口会立即关闭,对应你看到的“1秒左右消失的图”。
  2. plt.show(block=False)的特性:该调用会立即返回,主进程继续执行new()。如果new()内部也有plt.show()调用,再加上子进程意外生成的窗口,就会出现总共3个窗口。

解决方法

  • 隔离子进程的matplotlib环境:在子进程函数内部重新初始化matplotlib,避免继承主进程的绘图对象(matplotlib的绘图对象并非进程安全):
    def read():
        # 子进程中重新配置matplotlib后端
        import matplotlib
        matplotlib.use('TkAgg')  # 根据你的实际后端调整(如Qt5Agg、Agg等)
        import matplotlib.pyplot as plt
        
        # 这里编写读取数据的逻辑,避免使用主进程的fig对象
    
  • 避免跨进程共享绘图对象:主进程的fig、axes等对象不能在子进程中使用,必须在各自进程内独立创建绘图上下文。
  • 检查new()函数:确认new()内部的plt.show()是否伴随未指定num参数的plt.figure或plt.subplots调用,这类操作会默认创建新的绘图窗口,可能导致额外窗口出现。

内容的提问来源于stack exchange,提问作者Neha Durani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:20:47