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

PyCharm 2017.3.3社区版中Matplotlib仅断点调试时正常显示多图问题

解决Matplotlib循环绘图时仅显示首图且卡顿的问题

嘿,我刚好碰到过类似的问题!你在PyCharm 2017.3.3社区版里遇到的这个情况,本质是Matplotlib默认的阻塞式绘图机制在搞鬼——直接运行或无断点调试时,第一个plt.show()会卡住整个程序的执行,后面的循环代码根本没机会运行;而断点逐步调试时,你关闭当前窗口后程序才会继续执行下一次循环,所以所有图表都能正常显示。之前用更少图表运行没问题,是因为阻塞时间短没被你注意到,图表数量增多后这个问题就凸显出来了。

问题根源

Matplotlib默认使用的后端(比如TkAgg)在调用plt.show()时,会进入阻塞状态,直到你手动关闭当前绘图窗口才会继续执行后续代码。所以当你在循环里直接调用plt.show(),程序就会卡在第一个窗口,无法推进到下一次迭代。

可行解决方案

方案1:每次绘图后关闭窗口(最简单直接)

在每次循环的plt.show()之后,调用plt.close()关闭当前绘图窗口,让程序能继续执行下一次循环:

plt.show()
plt.close()  # 关闭当前窗口,释放资源,让程序继续往下走

方案2:启用交互式模式

在代码开头启用Matplotlib的交互式模式,这样plt.show()不会阻塞程序,所有图表会依次弹出,最后可以用plt.ioff()和plt.show()保持窗口不自动关闭:

import matplotlib.pyplot as plt
plt.ion()  # 启用交互式模式

# 你的循环绘图代码...

plt.ioff()  # 关闭交互式模式
plt.show()  # 保持所有窗口打开

方案3:使用面向对象式绘图(更优雅,推荐长期使用)

避开pyplot的全局状态,改用图和子图对象来管理绘图,能更精准控制每个窗口的生命周期:

# 替换循环内的绘图代码:
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))  # 创建图和子图对象
if not histData[0].empty or not histData[1].empty or not histData[2].empty:
    n, bins, patches = ax1.hist(histData, np.arange(0.5,13, 1), stacked=True, label=types, color=col, rwidth=0.8)
    ax1.legend()
    ax1.set_xticks(range(1,13))
    ax1.set_xticklabels(("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", 
                         "Septiembre", "Octubre", "Noviembre", "Diciembre"))
    ax1.set_title(f"Clase {comp+1} de {nclasses}")
    
    ax2.stem(mclass)
    ax2.set_xticks(range(14))
    ax2.set_xticklabels(list(df.loc[:, "M":"Salida2_4"]))
    ax2.set_title("Medias de características para la clase")
plt.show()
plt.close(fig)  # 关闭当前图对象

修正后的完整代码(用方案1快速解决)

这里给出直接修改后的代码,只加了一行plt.close(),适合你的场景:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.externals import joblib

feat_file = 'C:\\Users\\DianaCarolina\\Google Drive\\Maestría\\datos\\indices_Diana\\all_type.xlsx'
sites = {"Bosque":['5256', '5260'], "Rastrojo": ['5253', '5255'], "Pastizal": ['5257', '7125']}
model=joblib.load("C:\\Users\\DianaCarolina\\Google Drive\\Maestría\\datos\\indices_Diana\\ecotyhmm13_3.pkl")
nclasses = 13

for comp in range(nclasses):
    histData = []
    types = []
    col = []
    for type in sites:
        df = pd.read_excel(feat_file, sheet_name=type, index_col=0)
        mdata=df.loc[df.iloc[:, 20] == comp, "Mes"]
        types.append(type)
        histData.append(mdata)
        if len(col) < 3:
            if type == "Bosque" and "green" not in col:
                col.append("green")
            elif type == "Rastrojo" and "orange" not in col:
                col.append("orange")
            elif type == "Pastizal" and "yellow" not in col:
                col.append("yellow")
    mclass = np.sum(np.array([model.gmms_[comp].weights_]).T * model.gmms_[comp].means_, 0)
    plt.figure()
    if not histData[0].empty or not histData[1].empty or not histData[2].empty:
        plt.subplot(2, 1, 1)
        n, bins, patches = plt.hist(histData, np.arange(0.5,13, 1), stacked=True, label= types, color = col, rwidth=0.8)
        plt.legend()
        plt.xticks(range(1,13), ("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", \
        "Septiembre", "Octubre", "Noviembre", "Diciembre"))
        plt.title("Clase "+str(comp+1)+" de "+str(nclasses))
        plt.subplot(2, 1, 2)
        plt.stem(mclass)
        plt.xticks(range(14), list(df.loc[:, "M":"Salida2_4"]))
        plt.title("Medias de características para la clase")
    plt.show()
    plt.close()  # 新增:关闭当前窗口,让程序继续执行下一次循环

额外小建议

  • 如果你需要所有图表同时打开不关闭,方案2会更适合;如果看完一个关一个,方案1最省心。
  • 可以通过print(plt.get_backend())查看当前Matplotlib的后端,PyCharm社区版推荐用TkAgg或Qt5Agg这类交互式后端。
  • 循环里重复读取Excel文件效率很低,建议提前把所有数据读入内存再循环处理,能大幅提升运行速度哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:28