Matplotlib中plt.show()陷入无限循环,关闭窗口后脚本仍停滞
解决Matplotlib plt.show()关闭窗口后脚本停滞的问题
问题场景
调用plt.show()显示绘图窗口后,关闭窗口时脚本始终卡在该语句;设置block=False则窗口会立刻关闭,无法正常查看绘图。需求是关闭窗口后脚本能够继续执行或正常终止。
原代码:
fig = plt.figure(figsize=plt.figaspect(0.5)) mappable_zmax = plt.cm.ScalarMappable(cmap=plt.cm.viridis) mappable_zmax.set_array(Znew_max) mappable_zmin = plt.cm.ScalarMappable(cmap=plt.cm.viridis) mappable_zmin.set_array(Znew_min) # ============= # First subplot # ============= ax = fig.add_subplot(1, 2, 1, projection='3d') ax.plot_surface(Xnew, Ynew, Znew_max, rstride=1, cstride=1, cmap=cm.viridis, linewidth=0, antialiased=True) plt.xlabel('Frequency(Hz)') plt.ylabel('Duty(%)') plt.ticklabel_format(style='sci', axis='x', scilimits=(3,3)) plt.title() # ============== # Second subplot # ============== fig2 = fig.add_subplot(122) plt.pcolor(Xnew, Ynew, Znew_max, shading='auto') plt.xlabel('Frequency(Hz)') plt.ylabel('Duty(%)') plt.colorbar(mappable_zmax) plt.show()
解决方案
1. 检查并指定Matplotlib后端
部分交互式后端存在兼容性问题,会导致窗口关闭后脚本停滞。可手动指定稳定的后端,比如TkAgg或Qt5Agg:
import matplotlib matplotlib.use('TkAgg') # 优先尝试该后端,不行可换Qt5Agg import matplotlib.pyplot as plt
2. 配合plt.close('all')确保脚本继续执行
默认plt.show(block=True)在关闭窗口后应自动继续执行,但如果后端仍有问题,可在plt.show()后手动关闭所有绘图对象:
plt.show() plt.close('all') # 强制关闭所有figure,释放资源使脚本继续
3. 修复原代码中的细节问题
cm.viridis需改为plt.cm.viridis(或导入from matplotlib import cm后使用cm.viridis)plt.title()缺少标题内容,需传入字符串参数fig2 = fig.add_subplot(122)变量名错误,子图对象应命名为ax2而非fig2(fig是整个画布,add_subplot返回子图轴对象)
修改后的完整代码
import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt from matplotlib import cm # 假设Xnew, Ynew, Znew_max, Znew_min已提前定义 fig = plt.figure(figsize=plt.figaspect(0.5)) mappable_zmax = plt.cm.ScalarMappable(cmap=plt.cm.viridis) mappable_zmax.set_array(Znew_max) mappable_zmin = plt.cm.ScalarMappable(cmap=plt.cm.viridis) mappable_zmin.set_array(Znew_min) # 第一个子图:3D曲面图 ax = fig.add_subplot(1, 2, 1, projection='3d') ax.plot_surface(Xnew, Ynew, Znew_max, rstride=1, cstride=1, cmap=cm.viridis, linewidth=0, antialiased=True) plt.xlabel('Frequency(Hz)') plt.ylabel('Duty(%)') plt.ticklabel_format(style='sci', axis='x', scilimits=(3,3)) plt.title('Max Value 3D Surface') # 补充标题 # 第二个子图:伪彩色图 ax2 = fig.add_subplot(122) ax2.pcolor(Xnew, Ynew, Znew_max, shading='auto') plt.xlabel('Frequency(Hz)') plt.ylabel('Duty(%)') plt.colorbar(mappable_zmax) plt.show() plt.close('all') # 关闭所有figure,确保脚本正常结束
内容的提问来源于stack exchange,提问作者calugaruful
相关产品推荐
相关产品推荐

