Matplotlib plt.show()无法稳定显示全部子图问题求解
问题原因
- 绘图流程中重复调用了2次
plt.show():第一次调用位置在第2个子图绘制完成后、第3个子图绘制开始前。Jupyter Notebook的Matplotlib内联渲染模式下,执行到plt.show()会立刻输出当前画布的已绘制内容并结束当前画布的渲染流程,后续的绘图操作不会同步到已经输出的结果中,第二次调用plt.show()时只会输出未完成绘制的空白画布区域,这是显示异常的核心原因。 - 初始化了7行3列共21个子图对象,但仅为第一行的3个子图编写了绘图逻辑,剩余18个子图本身没有绑定任何绘图内容,会默认显示为空白框。
- 代码末尾的
plt.show()后多余的分号属于不规范写法,虽不直接导致报错,但会干扰部分环境下的渲染判断。
修复方法
调整代码逻辑遵循两个核心规则:多子图绘制全程仅保留1次plt.show()调用,且放在所有绘图逻辑的最末尾;按需初始化子图数量,避免生成无内容的空白子图。
修复后的可运行代码如下:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 开头加魔法命令固定渲染模式,避免偶发渲染异常 %matplotlib inline def min_avg_max_pol_city(num_cities = 5): # 若当前仅需绘制NO2相关的3张图,nrows设为1即可;后续要补充其他污染物图表时再调整为7 fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(22, 6)) # 同时调整横向、纵向子图间距,避免城市名、标题重叠 plt.subplots_adjust(hspace=0.4, wspace=0.3) # 子图1:NO2浓度最低的城市 no2_min = ax[0] sub_df = df[df['pollutant_id'] == 'NO2'].sort_values('pollutant_min', ascending=True).head(num_cities) sns.barplot(ax=no2_min, x=sub_df.city, y=sub_df.pollutant_min) no2_min.set_ylabel("污染浓度", fontsize=14) no2_min.set_title("NO2浓度最低的城市", fontsize=14) no2_min.tick_params(axis='x', rotation=30) # 旋转x轴标签避免文字重叠 # 子图2:NO2平均浓度最高的城市 no2_avg = ax[1] sub_df = df[df['pollutant_id'] == 'NO2'].sort_values('pollutant_avg', ascending=False).head(num_cities) sns.barplot(ax=no2_avg, x=sub_df.city, y=sub_df.pollutant_avg) no2_avg.set_title('NO2平均浓度最高的城市', fontsize=14) no2_avg.tick_params(axis='x', rotation=30) # 子图3:NO2浓度最高的城市 no2_max = ax[2] sub_df = df[df['pollutant_id'] == 'NO2'].sort_values('pollutant_max', ascending=False).head(num_cities) sns.barplot(ax=no2_max, x=sub_df.city, y=sub_df.pollutant_max) no2_max.set_title('NO2浓度最高的城市', fontsize=14) no2_max.tick_params(axis='x', rotation=30) # 所有绘图逻辑完成后,仅调用一次plt.show() plt.show() min_avg_max_pol_city(5)
后续扩展说明
如果需要保留7行3列的子图布局来展示其他污染物的统计结果,只需将nrows参数改回7,后续逐行给ax[行号,列号]对应的子图对象绑定绘图逻辑即可,切记不要在绘制中途插入plt.show()调用。
内容的提问来源于stack exchange,提问作者Twinkle Sahni
相关产品推荐
相关产品推荐

