Jupyter Notebook中plt.subplot生成2行3列子图异常问题问询
解决Jupyter Notebook中2行3列子图布局不符合预期的问题
我帮你排查出了子图布局异常的几个核心原因,同时整理了修正后的代码方案:
问题根源分析
plt.show()的时机错误:你的plot_it函数里每次绘图后立即调用plt.show(),这会强制Matplotlib把当前绘制的内容单独输出成一个独立的窗口/单元格结果,而不是把多个子图整合到同一个2×3的布局里。- 未绑定子图对象:
plot_it直接使用全局的plt.plot绘图,没有指定具体的子图容器,加上plt.show的干扰,导致子图布局完全混乱。 - 布局流程被中断:虽然开头调用了
plt.figure(),但后续的子图创建和绘图没有和这个figure绑定,且多次plt.show会打断Matplotlib的布局渲染流程。
修正后的代码
import matplotlib.pyplot as plt import numpy as np # 重构plot_it函数,接收子图对象作为参数 def plot_it(U1, U2, x, i, ax): fig_1, = ax.plot(x, U1) fig_2, = ax.plot(x, U2) # 处理时间步标签 i_label = str(int(i/2 + 1)) if i != 0 else '' ax.set_xlabel('x, t =' + i_label + 'Δt') ax.set_ylabel('U') ax.legend(handles=[fig_1, fig_2], labels=['μ = 1', 'μ = 2']) # 一次性创建2行3列的子图网格,同时指定画布大小(可选) fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 8)) # 将2×3的子图数组展平为一维,方便循环索引 axes = axes.flatten() for i in range(11): U1[1:20] = np.linalg.solve(A1, B1.dot(U1[1:20])) U2[1:20] = np.linalg.solve(A2, B2.dot(U2[1:20])) if i % 2 == 0: subplot_idx = int(i/2) # 确保不超出2×3=6个子图的范围 if subplot_idx < len(axes): plot_it(U1, U2, x, i, axes[subplot_idx]) # 自动调整子图间距,避免标签重叠 plt.tight_layout() # 所有子图绘制完成后,统一调用show渲染整个布局 plt.show()
关键改动说明
- 绑定子图对象:让
plot_it接收具体的子图对象ax,所有绘图操作都在这个子图上进行,彻底避免全局plt对象的干扰。 - 统一调用
plt.show():把plt.show()移到所有子图绘制完成后,确保Matplotlib将所有子图整合到同一个画布中输出。 - 使用
plt.subplots创建布局:一次性生成2行3列的子图网格,展平数组后可以通过索引直接访问每个子图,逻辑更清晰。 - 添加
plt.tight_layout():自动调整子图之间的间距和标签位置,解决子图标签重叠的问题。 - 索引边界检查:确保循环中不会尝试访问超出6个的子图(因为2×3布局最多容纳6个子图,对应i=0、2、4、6、8、10这6次绘图)。
内容的提问来源于stack exchange,提问作者Animeta
相关产品推荐
相关产品推荐

