第 10 章 保存与导出:savefig
学习目标
- 掌握
fig.savefig的基本用法与路径 - 理解
dpi与分辨率的关系 - 区分位图(PNG)与矢量图(PDF/SVG)
- 掌握
bbox_inches与transparent控制边距与背景 - 会为网页与打印分别选择合适的导出参数
10.1 savefig 的基本用法
fig.savefig(路径) 把 fig(Figure)保存成文件。路径的扩展名决定格式:
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(10)
x = np.arange(1, 31)
y = 40 + 20 * np.sin(x / 30 * 4 * np.pi) + rng.normal(0, 4, 30)
fig, ax = plt.subplots()
ax.plot(x, y, marker="o", markersize=3)
ax.set_title("30 天商品销量")
ax.set_xlabel("日期")
ax.set_ylabel("销量(件)")
ax.grid(True, alpha=0.3)
fig.savefig("sales.png") # 保存为 PNG图 10-1 就是 sales.png 的内容:

要点:
savefig是fig(Figure)的方法,不是ax的方法。- 路径可以带目录,如
fig.savefig("output/charts/sales.png"),但目录必须已存在(见 10.6)。 - 也可用
format=显式指定格式:fig.savefig("sales", format="png")。
10.2 dpi 与分辨率
dpi(dots per inch,每英寸点数) 决定图片的清晰度。图片的像素数 = 英寸大小 × dpi。一张 figsize=(7, 4.2) 的图:
dpi=72:约 504 × 302 像素,适合屏幕预览。dpi=150:约 1050 × 630 像素,网页常规够用。dpi=300:约 2100 × 1260 像素,适合打印。
fig.savefig("sales_web.png", dpi=150)
fig.savefig("sales_print.png", dpi=300)像素越大文件越大、加载越慢。网页用 150 左右足够;要放大打印才用 300。本书插图统一用 dpi=110 控制体积。
10.3 格式:位图与矢量图
Matplotlib 支持的格式分两大类:
| 格式 | 类型 | 特点 | 适用 |
|---|---|---|---|
| PNG | 位图 | 通用、体积可控、有损无损看设置 | 网页、PPT、聊天 |
| JPG | 位图 | 有损压缩,不支持透明 | 照片类(很少用于图表) |
| SVG | 矢量 | 无限缩放不糊、体积小 | 网页、编辑、后续改样式 |
| 矢量 | 印刷标准、可嵌入文档 | 论文、报告打印 | |
| EPS | 矢量 | 老式论文投稿格式 | LaTeX 论文 |
同一张图导出三种格式的真实文件大小:
png: 35944 字节
pdf: 11402 字节
svg: 27798 字节矢量图(PDF/SVG)存的是「线条和形状」而不是像素,放大多少倍都清晰,所以文件小且可编辑;位图(PNG)是固定像素,放大会糊。图 10-2 是导出前的原图:

10.4 边距与透明背景
默认边距:savefig 会保留图周围一圈空白。想让内容「贴边」,用 bbox_inches="tight",它会自动裁剪到刚好包住所有元素;pad_inches 控制裁剪后留多少边距:
fig.savefig("sales_tight.png", bbox_inches="tight", pad_inches=0.2)为了看清边距,下面两张图把 Figure 背景设成浅橙色。图 10-3 是默认保存(四周留白):

图 10-4 是 bbox_inches="tight" 之后(空白被裁剪掉):

透明背景:transparent=True 让背景变透明,适合把图叠在有色页面/PPT 上。下面把透明 PNG 放在浅蓝色底上,背景色透了出来:

图 10-5(透明背景 PNG,叠在浅蓝底上演示)。
10.5 为不同场景选择导出参数
| 场景 | 推荐 |
|---|---|
| 网页 / 博客 | PNG,dpi=150,bbox_inches="tight" |
| PPT / 文档 | PNG,dpi=300 或 PDF |
| 论文 / 印刷 | PDF 或 EPS(矢量) |
| 网页深色主题 | transparent=True |
| 放大查看 | SVG |
一句话:网页用 PNG+tight,印刷用 PDF/SVG。
10.6 读懂报错:目录不存在
保存到不存在的目录会报 FileNotFoundError:
>>> fig.savefig("/no/such/dir/out.png")
Traceback (most recent call last):
...
FileNotFoundError: [Errno 2] No such file or directory: '/no/such/dir/out.png'解读:Matplotlib 不会自动创建目录。修法:先 os.makedirs("output/charts", exist_ok=True) 再保存,或直接用已存在的目录。
动手实践
- 画一张图并保存为
my_figure.png,确认文件生成。 - 用
dpi=72与dpi=300各存一份,对比文件大小(用os.path.getsize)。 - 把同一张图分别存成 PNG、PDF、SVG,对比文件大小并观察三种格式的区别。
- 用
bbox_inches="tight"与transparent=True各保存一张,复现图 10-3~10-5 的效果。 - 故意保存到不存在的目录,读报错并用
os.makedirs(..., exist_ok=True)修复。
常见错误
| 错误写法 | 现象 | 原因 |
|---|---|---|
| 保存到不存在的目录 | FileNotFoundError | savefig 不自动建目录,先 os.makedirs |
用 ax.savefig(...) | AttributeError: 'Axes' object has no attribute 'savefig' | savefig 是 Figure 的方法 |
网页图用 dpi=72 | 文字发虚 | 分辨率太低,网页用 dpi=150 |
| 放大的图用 PNG | 放大后模糊 | 需要矢量图,改用 PDF/SVG |
忘了 bbox_inches="tight" | 图周围大片空白 | 用 bbox_inches="tight" 裁剪 |
| 保存后看不到图 | 路径找错 | 打印 os.path.abspath(路径) 确认位置 |
章末练习
基础
- 画一张图并保存为 PNG。
- 用
dpi=150保存,并打印文件大小。 - 保存一份 PDF 版本。
提高
- 对比
bbox_inches="tight"前后两张图的大小差异,说明pad_inches的作用。 - 把一张带透明背景的 PNG 叠在有色背景上验证透明效果。
挑战
- 写一个函数
export(fig, name, dpi=150, tight=True, transparent=False),封装保存逻辑,并用来批量导出三张不同的图。 - 用
savefig的format="svg"导出后,用文本编辑器打开 SVG 文件,找到其中表示线条的<path>标签,理解「矢量 = 存形状」这句话。
章末自测
每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。
savefig是哪个对象的方法?- A.
Axes - B.
Figure - C.
pyplot - D.
Tick
- A.
- 保存为 PDF 的正确写法?
- A.
fig.savefig("a.pdf") - B.
fig.savefig("a", format="png") - C.
ax.savefig("a.pdf") - D.
fig.export("a.pdf")
- A.
- 图片像素数 = ?
- A. 英寸 × dpi
- B. 英寸 + dpi
- C. dpi ÷ 英寸
- D. 与 dpi 无关
- 网页图表常用哪个 dpi?
- A. 72
- B. 150
- C. 600
- D. 1000
- 无限放大不模糊的格式是?
- A. PNG
- B. JPG
- C. SVG
- D. BMP
bbox_inches="tight"的作用是?- A. 把图变大
- B. 裁剪到刚好包住所有元素
- C. 加粗边框
- D. 压缩图片
- 让背景透明的参数是?
- A.
alpha=True - B.
transparent=True - C.
bgcolor=None - D.
clear=True
- A.
- 保存到不存在的目录会?
- A. 自动创建目录
- B.
FileNotFoundError - C. 保存到当前目录
- D. 静默失败
- 打印用的图表首选格式?
- A. PNG(dpi=72)
- B. JPG
- C. PDF(矢量)
- D. BMP
fig.savefig("sales", format="png")生成的默认文件名?- A.
sales.png - B.
sales - C.
sales.jpg - D.
png.sales
- A.
