Skip to content

第 10 章 保存与导出:savefig

学习目标

  • 掌握 fig.savefig 的基本用法与路径
  • 理解 dpi 与分辨率的关系
  • 区分位图(PNG)与矢量图(PDF/SVG)
  • 掌握 bbox_inchestransparent 控制边距与背景
  • 会为网页与打印分别选择合适的导出参数

10.1 savefig 的基本用法

fig.savefig(路径)fig(Figure)保存成文件。路径的扩展名决定格式:

python
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 的内容:

图 10-1 保存出的 PNG 图片

要点:

  • savefigfig(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 像素,适合打印。
python
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矢量无限缩放不糊、体积小网页、编辑、后续改样式
PDF矢量印刷标准、可嵌入文档论文、报告打印
EPS矢量老式论文投稿格式LaTeX 论文

同一张图导出三种格式的真实文件大小:

png: 35944 字节
pdf: 11402 字节
svg: 27798 字节

矢量图(PDF/SVG)存的是「线条和形状」而不是像素,放大多少倍都清晰,所以文件小且可编辑;位图(PNG)是固定像素,放大会糊。图 10-2 是导出前的原图:

图 10-2 导出演示用的原图

10.4 边距与透明背景

默认边距:savefig 会保留图周围一圈空白。想让内容「贴边」,用 bbox_inches="tight",它会自动裁剪到刚好包住所有元素;pad_inches 控制裁剪后留多少边距:

python
fig.savefig("sales_tight.png", bbox_inches="tight", pad_inches=0.2)

为了看清边距,下面两张图把 Figure 背景设成浅橙色。图 10-3 是默认保存(四周留白):

图 10-3 默认边距

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

图 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) 再保存,或直接用已存在的目录。

动手实践

  1. 画一张图并保存为 my_figure.png,确认文件生成。
  2. dpi=72dpi=300 各存一份,对比文件大小(用 os.path.getsize)。
  3. 把同一张图分别存成 PNG、PDF、SVG,对比文件大小并观察三种格式的区别。
  4. bbox_inches="tight"transparent=True 各保存一张,复现图 10-3~10-5 的效果。
  5. 故意保存到不存在的目录,读报错并用 os.makedirs(..., exist_ok=True) 修复。

常见错误

错误写法现象原因
保存到不存在的目录FileNotFoundErrorsavefig 不自动建目录,先 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(路径) 确认位置

章末练习

基础

  1. 画一张图并保存为 PNG。
  2. dpi=150 保存,并打印文件大小。
  3. 保存一份 PDF 版本。

提高

  1. 对比 bbox_inches="tight" 前后两张图的大小差异,说明 pad_inches 的作用。
  2. 把一张带透明背景的 PNG 叠在有色背景上验证透明效果。

挑战

  1. 写一个函数 export(fig, name, dpi=150, tight=True, transparent=False),封装保存逻辑,并用来批量导出三张不同的图。
  2. savefigformat="svg" 导出后,用文本编辑器打开 SVG 文件,找到其中表示线条的 <path> 标签,理解「矢量 = 存形状」这句话。

章末自测

每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。

  1. savefig 是哪个对象的方法?
    • A. Axes
    • B. Figure
    • C. pyplot
    • D. Tick
  2. 保存为 PDF 的正确写法?
    • A. fig.savefig("a.pdf")
    • B. fig.savefig("a", format="png")
    • C. ax.savefig("a.pdf")
    • D. fig.export("a.pdf")
  3. 图片像素数 = ?
    • A. 英寸 × dpi
    • B. 英寸 + dpi
    • C. dpi ÷ 英寸
    • D. 与 dpi 无关
  4. 网页图表常用哪个 dpi?
    • A. 72
    • B. 150
    • C. 600
    • D. 1000
  5. 无限放大不模糊的格式是?
    • A. PNG
    • B. JPG
    • C. SVG
    • D. BMP
  6. bbox_inches="tight" 的作用是?
    • A. 把图变大
    • B. 裁剪到刚好包住所有元素
    • C. 加粗边框
    • D. 压缩图片
  7. 让背景透明的参数是?
    • A. alpha=True
    • B. transparent=True
    • C. bgcolor=None
    • D. clear=True
  8. 保存到不存在的目录会?
    • A. 自动创建目录
    • B. FileNotFoundError
    • C. 保存到当前目录
    • D. 静默失败
  9. 打印用的图表首选格式?
    • A. PNG(dpi=72)
    • B. JPG
    • C. PDF(矢量)
    • D. BMP
  10. fig.savefig("sales", format="png") 生成的默认文件名?
    • A. sales.png
    • B. sales
    • C. sales.jpg
    • D. png.sales