我的知识记录

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标签会自动隐藏,版面更干净。

Python matplotlib多子图subplot:一张图放多个子图

标签:

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

上一篇:Python生成月度销售报表图表:自动汇总出图

下一篇:Python matplotlib画散点图:分析两组数据相关性