Matplotlib.pyplot在Jupyter Notebook分单元格执行时保存空白图片且plt.show()无输出的问题
解决Jupyter中Matplotlib拆分单元格绘图失效的问题
嘿,我来帮你搞定这个头疼的问题!你遇到的核心问题其实是Matplotlib的全局状态管理漏洞加上代码里一个容易踩的小坑——错误调用了plt.subplot()。
问题根源拆解
plt.subplot()的误用:你在已经用plt.bar()绘制完柱状图之后调用了ax = plt.subplot(),这行代码会创建一个全新的Axes(子图)对象,直接覆盖掉你之前绘制了柱状图的那个Axes!当代码在同一个单元格时,Matplotlib的全局上下文还能勉强把后续的设置(比如刻度)关联到新的Axes,但拆分到不同单元格时,每个单元格执行后全局状态会被重置,之前的绘图就彻底丢失了,自然会出现plt.show()无输出、保存空白图的情况。- 单元格拆分后的状态丢失:Matplotlib的pyplot接口依赖全局的Figure和Axes状态,拆分单元格后,前一个单元格创建的绘图上下文在后续单元格中可能无法正确引用,导致操作失效。
修正方案
方案1:快速修复原代码(适合小调整)
把ax = plt.subplot()替换成ax = plt.gca()(get current axes,获取当前已存在的Axes),这样就不会创建新的子图覆盖原有绘图了。拆分单元格的示例如下:
单元格1:导入库+准备数据+初始化绘图
%matplotlib inline from matplotlib import pyplot as plt # 准备数据 past_years_averages = [82, 84, 83, 86, 74, 84, 90] years = [2000, 2001, 2002, 2003, 2004, 2005, 2006] error = [1.5, 2.1, 1.2, 3.2, 2.3, 1.7, 2.4] # 创建画布并绘制柱状图 plt.figure(figsize=(10, 8)) plt.bar(range(len(past_years_averages)), past_years_averages, yerr=error, capsize=5) plt.axis([-0.5, 6.5, 70, 95]) # 获取当前已有的Axes,不要创建新的! ax = plt.gca()
单元格2:设置刻度和标签
# 设置X轴刻度和年份标签 ax.set_xticks(range(len(years))) ax.set_xticklabels(years) # 添加标题和坐标轴标签 plt.title("Final Exam Averages") plt.xlabel("Year") plt.ylabel("Test average")
单元格3:保存并显示图形
plt.savefig("my_bar_chart.png") plt.show()
方案2:推荐使用面向对象写法(彻底避免状态问题)
Matplotlib的面向对象接口(直接操作Figure和Axes对象)不依赖全局状态,不管怎么拆分单元格都不会出问题,代码也更清晰:
单元格1:导入库+准备数据+创建画布和子图
%matplotlib inline from matplotlib import pyplot as plt # 准备数据 past_years_averages = [82, 84, 83, 86, 74, 84, 90] years = [2000, 2001, 2002, 2003, 2004, 2005, 2006] error = [1.5, 2.1, 1.2, 3.2, 2.3, 1.7, 2.4] # 显式创建画布和子图对象 fig, ax = plt.subplots(figsize=(10, 8))
单元格2:绘制柱状图并设置坐标轴范围
# 用Axes对象绘制柱状图 ax.bar(range(len(past_years_averages)), past_years_averages, yerr=error, capsize=5) # 设置坐标轴范围(替代plt.axis()) ax.set_xlim(-0.5, 6.5) ax.set_ylim(70, 95)
单元格3:设置刻度、标题和标签
# 设置X轴刻度和年份标签 ax.set_xticks(range(len(years))) ax.set_xticklabels(years) # 添加标题和坐标轴标签(全部用Axes对象的方法) ax.set_title("Final Exam Averages") ax.set_xlabel("Year") ax.set_ylabel("Test average")
单元格4:保存并显示图形
# 用Figure对象保存图片 fig.savefig("my_bar_chart.png") plt.show()
额外注意事项
- 确保单元格按顺序执行,不要跳过创建
fig和ax的单元格,因为后续代码需要引用这些对象。 - 如果还是有问题,可以尝试重启内核后按顺序重新执行所有单元格,清除之前的全局状态残留。
内容的提问来源于stack exchange,提问作者Punit Choudhary
相关产品推荐
相关产品推荐

