Python matplotlib多子图subplot:一张图放多个子图
用Python matplotlib的subplot和subplots在一张画布上排列多个子图,2行2列、不同图表类型混排,含间距调整和统一标题,代码完整。
场景痛点
做季度总结报告时,一页PPT想同时放销售额趋势、柱状对比、饼图占比、散点相关性四张图。Excel里要插四个图表再手动排版,对齐、调间距、统一风格特别费劲。用matplotlib的subplot,几行代码就能把多张图按网格排列在一张画布上,还能共享坐标轴、统一标题,导出的图直接贴报告。
用到的库
pip install matplotlib pandas
完整代码
# 导入库
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
# 解决中文乱码
matplotlib.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "Arial Unicode MS"]
matplotlib.rcParams["axes.unicode_minus"] = False
def draw_subplots():
# 准备数据
months = ["1月", "2月", "3月", "4月", "5月", "6月"]
sales = [120, 150, 180, 160, 210, 260]
costs = [80, 95, 110, 100, 130, 150]
regions = ["华东", "华南", "华北", "西部"]
region_sales = [450, 320, 280, 150]
# 创建 2行2列 的子图布局
fig, axes = plt.subplots(2, 2, figsize=(12, 9))
fig.suptitle("上半年经营数据总览", fontsize=18, fontweight="bold")
# 左上:折线图 - 销售额趋势
ax1 = axes[0][0]
ax1.plot(months, sales, marker="o", color="#4C72B0", linewidth=2)
ax1.set_title("月度销售额趋势")
ax1.set_ylabel("销售额(万元)")
ax1.grid(linestyle="--", alpha=0.5)
# 右上:柱状图 - 成本对比
ax2 = axes[0][1]
ax2.bar(months, costs, color="#55A868", alpha=0.7)
ax2.set_title("月度成本支出")
ax2.set_ylabel("成本(万元)")
# 左下:饼图 - 区域销售占比
ax3 = axes[1][0]
ax3.pie(region_sales, labels=regions, autopct="%1.1f%%", startangle=90)
ax3.set_title("各区域销售占比")
# 右下:柱状图 - 销售 vs 成本
ax4 = axes[1][1]
x = range(len(months))
ax4.bar([i - 0.2 for i in x], sales, width=0.4, label="销售额", color="#4C72B0")
ax4.bar([i + 0.2 for i in x], costs, width=0.4, label="成本", color="#C44E52")
ax4.set_title("销售额与成本对比")
ax4.set_xticks(list(x))
ax4.set_xticklabels(months)
ax4.legend()
# 调整子图间距
plt.tight_layout()
# suptitle 和 tight_layout 可能重叠,给顶部留空间
fig.subplots_adjust(top=0.90)
plt.savefig("subplots.png", dpi=150)
plt.close()
print("多子图已保存为 subplots.png")
if __name__ == "__main__":
draw_subplots()
代码讲解
plt.subplots(2, 2)一次性创建2行2列的子图网格,返回fig画布对象和axes二维数组,axes[0][0]就是左上子图。- 每个子图用对应的
ax.plot()、ax.bar()、ax.pie()画图,方法名和plt.xxx()一样,只是多了ax.前缀。 fig.suptitle()是整张图的大标题,ax.set_title()是每个子图自己的小标题。plt.tight_layout()自动调整子图间距防止标签重叠;fig.subplots_adjust(top=0.90)给最顶部的大标题留出空间。- 如果只要1行3列,写成
plt.subplots(1, 3),axes就是一维数组,直接axes[0]、axes[1]、axes[2]。
运行结果
当前目录生成 subplots.png,一张图里分四个象限:左上销售额折线、右上成本柱状、左下区域饼图、右下销售成本对比柱。顶部有总标题"上半年经营数据总览"。打开确认四张图都正常显示、中文无乱码。
注意事项
- 子图数量超过 3×3 时,单张图会太小,建议拆成两张图或用Pyecharts做交互式页面。
- 用
plt.subplots()后不要混用plt.plot()和ax.plot(),统一用ax.xxx写法,否则图画错地方。 - 子图之间共享X轴可以加
sharex=True参数,底部子图的X标签会自动隐藏,版面更干净。

更新时间:2026-09-14 20:29:03