Python循环生成多幅4行5列子图的实现方法
实现方案
核心逻辑:4行5列布局单张图最多放置20张子图,85组子集刚好对应5张图(前4张各承载20组数据,最后1张承载5组数据)。实现时先将所有子集按20个为一批切分,逐批生成画布,绘制完有效子图后隐藏多余空白轴即可。
参考代码
import matplotlib.pyplot as plt import pandas as pd # ———— 参数配置区,可根据实际需求修改 ———— # 将df拆分为85个子集,示例为按指定字段分组的写法,替换为你实际的子集生成逻辑即可 # 如果已有现成的子集列表,直接给subsets赋值为按顺序存放85个DataFrame的列表即可 subsets = [g for _, g in df.groupby("你的分组字段名")] rows_per_fig = 4 cols_per_fig = 5 subplot_per_fig = rows_per_fig * cols_per_fig # 单画布共20个子图位置 figsize = (20, 16) # 单张画布尺寸,可根据显示效果调整 # ———— 参数配置区结束 ———— total_subset = len(subsets) # 向上取整计算需要生成的总画布数 total_fig = (total_subset + subplot_per_fig - 1) // subplot_per_fig for fig_idx in range(total_fig): # 生成4行5列的子图画布 fig, axs = plt.subplots(nrows=rows_per_fig, ncols=cols_per_fig, figsize=figsize) # 将二维轴数组拉平为一维,方便按索引遍历 axs_flat = axs.flatten() # 计算当前画布需要绘制的子集范围 start_idx = fig_idx * subplot_per_fig end_idx = min(start_idx + subplot_per_fig, total_subset) current_batch = subsets[start_idx:end_idx] # 逐个绘制有效子图 for plot_idx, subset_data in enumerate(current_batch): ax = axs_flat[plot_idx] # 替换为你实际的绘图逻辑,支持折线、柱状、散点等任意matplotlib支持的图表类型 ax.plot(subset_data["x列名"], subset_data["y列名"], linewidth=1) ax.set_title(f"子集 {start_idx + plot_idx + 1}", fontsize=10) # 可按需追加坐标轴标签、图例、刻度调整等配置 # 隐藏当前画布未使用的多余子图,保留纯白空白 for empty_ax_idx in range(len(current_batch), subplot_per_fig): axs_flat[empty_ax_idx].axis("off") # 自动调整子图间距,避免标签、标题重叠 plt.tight_layout() # 如需本地保存图片可取消注释下一行,自定义存储路径和分辨率 # plt.savefig(f"批量绘图结果_{fig_idx+1}.png", dpi=150, bbox_inches="tight") plt.show() # 批量生成大量图片时建议取消注释下一行,及时释放内存避免程序卡顿 # plt.close()
调整说明
- 若需要统一所有子图的x/y轴显示范围,可在遍历绘制子图前添加
plt.setp(axs_flat, xlim=(x_min, x_max), ylim=(y_min, y_max))批量设置,无需逐个子图重复配置 - 子图默认按从左到右、从上到下的顺序排列,最后一张图的5个有效子图会自动占满第一行+第二行第一个位置,剩余位置完全隐藏坐标轴
- 若需要修改子图间距、配色、字体等样式,直接在
plt.subplots初始化或子图绘制环节调整对应参数即可
内容的提问来源于stack exchange,提问作者John Chae
相关产品推荐
相关产品推荐

