【Python系列课程】Matplotlib(四):子图布局与图像保存——subplot、axes、savefig
·
📊 阅读时长:12分钟 | 关键词:Matplotlib、subplot子图、axes画图中图、savefig保存、动态图
引言
一篇论文或报告中,常常需要把多张图放在一起对比。Matplotlib 提供了 subplot() 排布子图和 axes() 画图中图两种方式,最后用 savefig() 保存为图片文件。这是 Matplotlib 系列的收官篇。
一、plt.subplot() 创建子图
在一个画布上按"行 × 列"的网格排布多个子图:
plt.subplot(2, 2, 1) 2行 × 2列,第1个位置
plt.subplot(2, 2, 2) 2行 × 2列,第2个位置
plt.subplot(2, 2, 3) 2行 × 2列,第3个位置
plt.subplot(2, 2, 4) 2行 × 2列,第4个位置
┌─────────┬─────────┐
│ (1) │ (2) │
├─────────┼─────────┤
│ (3) │ (4) │
└─────────┴─────────┘
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2
y3 = np.sin(x)
y4 = np.tan(x)
plt.figure(figsize=(10, 8))
# 2行2列,第1个
plt.subplot(2, 2, 1)
plt.plot(x, y1)
plt.title('直线')
# 2行2列,第2个
plt.subplot(2, 2, 2)
plt.plot(x, y2, color='red')
plt.title('抛物线')
# 2行2列,第3个
plt.subplot(2, 2, 3)
plt.plot(x, y3, color='green')
plt.title('正弦曲线')
# 2行2列,第4个
plt.subplot(2, 2, 4)
plt.plot(x, y4, color='orange')
plt.title('正切曲线')
plt.tight_layout() # 自动调整子图间距
plt.show()
参数:plt.subplot(nrows, ncols, index)
| 参数 | 说明 |
|---|---|
nrows |
行数 |
ncols |
列数 |
index |
第几个子图(从 1 开始,按行从左到右编号) |
不规则布局
子图不必占满规则网格——可以在部分位置画图:
plt.figure(figsize=(10, 6))
# 2行1列,第1个(占上半部分整行)
plt.subplot(2, 1, 1)
plt.plot(x, y1, color='blue')
plt.title('直线')
# 2行3列,第4个(下半部分左侧)
plt.subplot(2, 3, 4)
plt.plot(x, y2, color='red')
plt.title('抛物线')
# 2行3列,第5个(下半部分中间)
plt.subplot(2, 3, 5)
plt.plot(x, y3, color='green')
plt.title('正弦曲线')
# 2行3列,第6个(下半部分右侧)
plt.subplot(2, 3, 6)
plt.plot(x, y4, color='orange')
plt.title('正切曲线')
plt.tight_layout()
plt.show()
┌────────────────────────────┐
│ (1) 上半部 │
│ 2行1列 第1个 │
├─────────┬────────┬─────────┤
│ (4) │ (5) │ (6) │
│ 2行3列 │ 2行3列 │ 2行3列 │
│ 第4个 │ 第5个 │ 第6个 │
└─────────┴────────┴─────────┘
💡 技巧:上半用
subplot(2,1,1),下半用subplot(2,3,4)—subplot(2,3,6),Matplotlib 自动对齐。
二、plt.axes() 画图中图
axes() 不强求网格布局,而是在画布的任意位置上独立放置一个坐标系:
x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2
y3 = np.sin(x)
plt.figure(figsize=(8, 6))
# 主图:占画布 80%,左下角在 (10%, 10%) 位置
plt.axes([0.1, 0.1, 0.8, 0.8])
plt.title('直线')
plt.plot(x, y1)
# 小图1:占画布 25%,放在右上角 (20%, 60%) 位置
plt.axes([0.2, 0.6, 0.25, 0.25])
plt.title('抛物线')
plt.plot(x, y2, color='red')
# 小图2:占画布 25%,放在右下角 (60%, 20%) 位置
plt.axes([0.6, 0.2, 0.25, 0.25])
plt.plot(x, y3, color='green')
plt.title('余弦曲线')
plt.show()
[0.1, 0.1, 0.8, 0.8] 这四个数字的含义:
0.1, 0.1 → 坐标框左下角在画布 10%, 10% 的位置
0.8, 0.8 → 坐标框的宽和高都是画布的 80%
💡
axes()适合"主图 + 局部放大"、"主图 + 辅助子图"这类非规则布局。
三、plt.savefig() 保存图像
plt.figure()
x = np.linspace(-3, 3, 50)
plt.plot(x, np.sin(x), color='blue')
plt.title('正弦曲线')
# 保存到文件
plt.savefig('./sine_wave.jpg')
plt.savefig('./sine_wave.png', dpi=300) # 高分辨率 PNG
plt.savefig('./sine_wave.svg') # 矢量图(放大不失真)
| 参数 | 说明 |
|---|---|
fname |
文件路径,后缀决定格式(.jpg / .png / .svg / .pdf) |
dpi |
分辨率,默认 100,设 300 适合印刷 |
bbox_inches |
'tight' 自动裁剪白边 |
facecolor |
背景颜色 |
四、bonus:动态图(plt.pause)
数据变化时,可以用 plt.pause() 和 plt.clf() 做简单的动画效果:
y2 = []
y1 = np.linspace(-3, 3, 50)
for i in y1**2:
y2.append(i)
plt.clf() # 清除上一次的数据
plt.plot(y2)
plt.pause(0.1) # 暂停 0.1 秒
# 你会看到曲线一段一段"生长"出来
plt.savefig('./parabola.jpg')
plt.clf()= clear figure,清除当前画布plt.pause(seconds)= 暂停指定的秒数
小结
| 函数 | 用途 | 用法 |
|---|---|---|
plt.subplot(r, c, i) |
规则网格布局 | 2×2 四宫格、1×3 横向排列 |
plt.axes([l, b, w, h]) |
任意位置放坐标系 | 主图+局部放大、画图中图 |
plt.savefig(path) |
保存为图片文件 | png/jpg/svg/pdf 多种格式 |
plt.clf() + plt.pause() |
动态更新 | 简单动画效果 |
🎉 Matplotlib 系列完结
| 篇目 | 内容 |
|---|---|
| (一) | plt.plot() 基础绘图、figure 画布、中文显示 |
| (二) | 坐标轴设置、spines 边框、legend 图例、text 标注 |
| (三) | scatter 散点图、bar 条形图、imshow 热力图 |
| (四) | subplot 子图、axes 画图中图、savefig 保存 |
掌握了这 4 篇,日常数据可视化基本够了。之后遇到更高级的需求(3D 图、交互式图表),Seaborn 和 Plotly 会是好帮手。
本文是「Python从入门到数据分析」系列的第 22 篇,也是 Matplotlib 系列的终篇。🎯 全系列 22 篇文章,从 Python 基础变量到数据分析可视化,完整覆盖了"入门到数据分析"的全路径。
📚 全系列导航:
Python 基础 → 函数/模块/面向对象 → NumPy → Pandas → Matplotlib
更多推荐


所有评论(0)