1.5 保存图像


文档摘要

1.5 保存图像 本节摘要:savefig 是 Matplotlib 把内存里的 Figure 固化成图像文件的出口函数,它通过文件名后缀或 format 参数决定格式,通过 dpi 决定分辨率,还能用 transparent、bboxinches 等参数控制背景透明和空白裁剪。保存不是"存一下"这么简单——格式选错,图会糊或有伪影;DPI 选错,要么文件大得离谱,要么印刷出来全是锯齿。本节讲清格式怎么选、分辨率怎么定、透明和裁剪各有什么用,让你存出来的图能在正确的场合被正确使用。

1.5 保存图像

本节摘要:savefig 是 Matplotlib 把内存里的 Figure 固化成图像文件的出口函数,它通过文件名后缀或 format 参数决定格式,通过 dpi 决定分辨率,还能用 transparent、bbox_inches 等参数控制背景透明和空白裁剪。保存不是"存一下"这么简单——格式选错,图会糊或有伪影;DPI 选错,要么文件大得离谱,要么印刷出来全是锯齿。本节讲清格式怎么选、分辨率怎么定、透明和裁剪各有什么用,让你存出来的图能在正确的场合被正确使用。

先说结论

阅读完本节,你应当能够:

  1. 说清 savefig 如何通过文件名后缀和 format 参数决定输出格式
  2. 对比 PNG、SVG、PDF、JPG 四种格式的优劣,判断各自适用场合
  3. 解释 DPI 的含义,并根据网页、演示、印刷三档选择合适值
  4. 用 transparent 和 bbox_inches 控制背景透明与空白裁剪
  5. 组合多个参数,一次性存出符合交付要求的高质量图像

一、保存不是"顺手存一下"

很多人学画图,最后一步随手 savefig 一下就算完事,结果交出去才发现:放在网页上模糊、印在纸上发虚、或者文件大得邮件都发不出去。问题往往不在画图,而在保存时没想清楚两件事:存成什么格式、存成多清晰。

保存这一步,本质上是在回答"这张图最终要去哪"。去向不同,选择就完全不同:

  • 要去网页,追求加载快、缩放不糊,矢量格式是首选。
  • 要去演示幻灯片,需要高清但文件别太大。
  • 要去印刷出版,需要高分辨率,锯齿在放大后会露馅。
  • 要去文档报告,最好能无损缩放、可嵌入文字。

把这些"去向"想清楚,下面讲的格式和 DPI 就有了判断的锚点。否则你只是在碰运气地填参数。

💡 关键直觉:保存之前先问一句"这张图最终出现在哪",答案决定了格式和分辨率。想不清去向,再高的 DPI、再贵的格式,都可能是错的。

二、格式怎么选:四种主流格式的取舍

Matplotlib 最核心的保存函数是 savefig。它有个很省心的特性——根据文件名的后缀自动判断格式。你写 savefig("chart.png"),它存成 PNG;写 savefig("chart.pdf"),它存成 PDF。如果想更明确,也可以用 format 参数显式指定,两者效果一样。

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], [1, 4, 2]) plt.savefig("chart.png") # 靠后缀判断,存成 PNG plt.savefig("chart.pdf", format="pdf") # 显式指定,存成 PDF

格式的差别,核心在"栅格"和"矢量"之分。栅格格式(PNG、JPG)把图存成一格一格的像素点,放大到一定程度就露马赛克;矢量格式(SVG、PDF)把图存成"线条和文字的数学描述",放大多少倍都清晰。这个区分是选格式的底层逻辑。

格式 类型 特点 适用场合
PNG 栅格,无损压缩 清晰、支持透明背景、文件适中 大多数图表的默认选择
SVG 矢量 无损缩放、可编辑、文件小 网页、需要缩放的图
PDF 矢量 可嵌文字、多页、适合排版 报告、论文、文档
JPG 栅格,有损压缩 文件小但可能出伪影 照片类,图表慎用

这里要特别提一句 JPG。它靠丢弃细节换小体积,对照片这种复杂图像合适,但用在折线图、柱状图这类"线条加纯色块"的图表上,往往会在边缘产生一圈模糊的伪影,图越简单越明显。所以画图表,能不用 JPG 就别用,PNG 和 SVG 是更稳的选择。

⚠️ 常见坑:别拿 JPG 存图表。它为了压缩体积丢掉细节,会在线条和色块边缘留下伪影,图越简单越明显。图表优先 PNG(要透明或日常用)或 SVG、PDF(要缩放或印刷)。

三、DPI:清晰度和文件大小的天平

DPI(每英寸点数)是控制分辨率的核心参数。它表示"每英寸里画多少个像素点",值越高,图越清晰,但文件也越大、渲染越慢。

理解 DPI,要把它和 1.2 节的 figsize 连起来看:最终图片的像素尺寸 = figsize 的英寸数 × dpi。 一张 8×6 英寸的画布,用 100 DPI 存出来是 800×600 像素,用 300 DPI 存出来就是 2400×1800 像素。所以想让图"更大更清",要么加 figsize,要么加 dpi,两者是乘法关系。

import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 6)) ax.plot([1, 2, 3], [1, 4, 2]) plt.savefig("low.png", dpi=72) # 低分辨率,适合网页 plt.savefig("high.png", dpi=300) # 高分辨率,适合印刷

DPI 的选择可以按"去向"分三档:

  • 网页显示:72 到 96 DPI 就够,屏幕本身分辨率有限,高了浪费。
  • 屏幕演示:100 到 150 DPI,兼顾清晰和文件大小。
  • 印刷出版:300 DPI 是通行标准,杂志海报可能要到 600。

💡 关键直觉:DPI 不是越高越好,而是"够用就行"。给网页存一张 600 DPI 的图,除了让文件膨胀、加载变慢,读者在屏幕上根本看不出差别。先定去向,再定 DPI,别盲目拉满。

四、透明背景与空白裁剪

除了格式和 DPI,还有两个参数能显著影响图的实际观感:transparentbbox_inches

transparent=True 让背景变透明。默认背景是不透明的白色,透明背景的图可以直接叠在彩色网页、深色幻灯片或其他图片上,不会出现一个难看的白方块。它主要对 PNG 和 PDF 有效——JPG 不支持透明。

plt.savefig("chart_transparent.png", transparent=True)

bbox_inches="tight" 则解决另一个问题:图周围的空白太大。 默认保存时,Matplotlib 会把整个画布都存下来,包括内容之外的一大圈留白。加了这个参数,它会自动计算内容实际占用的区域,把多余的空白裁掉,让图更紧凑。

plt.savefig("chart_tight.png", bbox_inches="tight")

这个参数还有一个隐藏价值:当你的图例或标题不小心超出了画布范围,默认保存会把超出的部分切掉,而 bbox_inches="tight" 会反过来把边界框扩大到正好包住这些元素,保证它们完整落进图里。所以凡是图例放到了框外,记得加这个参数。

⚠️ 常见坑:图例或标题被切掉一半,几乎都是因为没加 bbox_inches="tight"。只要内容有溢出画布的可能,就顺手加上这个参数,成本极低,却能避免返工。

五、一次存出合格的图

把前面讲的参数串起来,一次保存就能覆盖绝大多数交付场景。下面是一个综合示例:画一张带两条线、有图例和网格的图,然后分别存成适合网页的 SVG 和适合印刷的高清 PNG。

import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 10, 200) fig, ax = plt.subplots(figsize=(8, 6)) ax.plot(x, np.sin(x), label="正弦", linewidth=2) ax.plot(x, np.cos(x), label="余弦", linestyle="--") ax.set_title("正弦与余弦曲线") ax.set_xlabel("横轴") ax.set_ylabel("纵轴") ax.legend() ax.grid(True, linestyle=":", alpha=0.5) # 网页用:矢量、可缩放、背景透明 plt.savefig("curve.svg", format="svg", bbox_inches="tight", transparent=True) # 印刷用:栅格、高分辨率、裁掉多余空白 plt.savefig("curve.png", format="png", dpi=300, bbox_inches="tight")

这段代码里每个参数都有明确的目的:bbox_inches="tight" 裁掉空白并保住可能溢出的元素,transparent=True 让网页图能融入任意背景,dpi=300 保证印刷清晰。它们不是随手堆上去的,而是各自对应一个"去向"带来的需求。

到这里,你已经走完了从建画布到存文件的完整链路。但"保存"还有更细的控制——比如 PDF 的页面方向、元数据嵌入、JPEG 的压缩质量等,这些属于进阶内容,等你真正需要交付特定格式时再查官方文档即可。现在把基础这套吃透,已经能应付绝大多数日常场景。

六、背景和边缘颜色:facecolor 与 edgecolor

格式、DPI、透明、裁剪之外,还有两个控制画布外观的参数:facecolor(背景色)和 edgecolor(边缘色)。它们作用在整张 Figure 上,影响存出来的图片"底色"和"外框"。

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], [1, 4, 2]) plt.savefig("styled.png", facecolor="lightgray", edgecolor="black")

默认背景是白色。facecolor 能把它换成浅灰、米白,甚至深色——深色背景配浅色线条,就是常说的"夜间模式"图表,在深色主题的幻灯片或网页里很协调。edgecolor 控制画布边缘那圈线的颜色,平时用得少,但做白底图嵌进白色网页时,加一圈浅色边缘能避免图"融"进背景里。

这两个参数和 transparent 有交集,但分工不同:transparent=True 是让背景彻底透明,facecolor 是给背景一个具体颜色。要叠加到彩色背景上,用 transparent=True;要一个固定的深色或浅色底,用 facecolor。二者别混着用——设了透明,facecolor 的颜色就等于白设。

七、几个进阶但实用的参数

savefig 还有几个参数不常用,但特定场景下能省很多事,值得知道它们存在:

  • orientation(仅 PDF):设页面方向,"landscape" 横向、"portrait" 纵向。存报告用的 PDF 时,横向更适合宽幅图表。
  • papertype(仅 PDF):设纸张类型,比如 "a4""letter",决定 PDF 页面按哪种纸的尺寸排。
  • metadata:往图像文件里嵌入元数据,比如作者、标题。这些信息能被一些图片查看器和文档工具读出来,方便归档和溯源。
  • pil_kwargs:把额外的参数透传给底层的图像处理库,比如存 JPG 时指定压缩质量。
plt.savefig("report.pdf", format="pdf", orientation="landscape", papertype="a4", metadata={"Author": "数据分析组", "Title": "销售趋势"})

这些参数不必现在就背,但要知道"有这回事"。真到需要交付特定格式、满足特定要求时,你至少知道该往哪个方向去找,而不是抓瞎。

八、一个贯穿始终的心法:先定去向,再定参数

把这一节串起来,其实就一句话:保存的所有参数,都是"去向"决定的。 图要去网页,就选 SVG、透明背景、低 DPI;图要去印刷,就选 PNG 或 PDF、高 DPI、裁掉空白;图要嵌进深色幻灯片,就配深色背景或透明背景。

很多人保存出问题,不是不会用参数,而是没先想清楚去向,就随手点保存。结果要么图糊了,要么文件大得离谱,要么格式根本用不上。反过来,只要在保存前花十秒钟问一句"这张图最终出现在哪",后面的格式、DPI、透明、裁剪,全都有了判断依据。

💡 关键直觉:把"去向"当成保存的第一参数。它不写在代码里,却决定了代码里每一个保存参数该怎么填。

九、为什么我存出来的图是空白的?

这是个新手高频踩坑:代码里明明画了图,存出来的文件却是一片空白。十有八九,是把 savefig 写在了 show 之后。

原因在于,show 在显示完图之后,可能会把 Figure 从内存里释放掉;这时再调 savefig,它保存的是一个已经被清空、或者已经进入不一致状态的画布,自然就是空白。正确的顺序是savefig 保存,再 show 显示——先固化到文件,再展示到屏幕,两者不冲突。

import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], [1, 4, 2]) plt.savefig("chart.png") # 先保存 plt.show() # 后显示

⚠️ 记住这个顺序:先存后显。凡是"存出来的图是空白"的报障,先检查 savefig 是不是被放在了 show 之后,这是最常见、也最好修的原因。

十、图上的中文保存后变成方框怎么办

中文保存后显示成方框或乱码,是 Matplotlib 很常见的现象,根因是它默认使用的字体里没有中文字形。这不是你代码写错了,而是字体配置的问题——需要给 Matplotlib 指定一个支持中文的字体。这个话题牵扯到字体查找、文本渲染的细节,第 4 章"文本渲染与字体"会给出完整解法。这里先给你一个心理预期,避免遇到方框时误以为是保存参数出问题。

重点提炼

  • 保存前先问"图最终去哪",去向决定格式和 DPI。
  • savefig 靠文件后缀或 format 参数决定格式,两者等价。
  • 栅格与矢量是底层分野:PNG、JPG 是栅格,SVG、PDF 是矢量,矢量无损缩放。
  • 图表慎用 JPG,它压缩会在线条边缘产生伪影;优先 PNG、SVG、PDF。
  • 像素尺寸 = figsize × dpi,想更大更清,两边都能调。
  • DPI 分三档:网页 72–96、演示 100–150、印刷 300 起,别盲目拉满。
  • transparent 控背景透明,bbox_inches 控空白裁剪,图例溢出时后者能救命。

到这里,第 1 章"基础入门"的五节就全部走完了。你已经能从零建画布、画四种基础图、调参数、存文件。下一章我们将在这个地基上盖楼——多子图、颜色映射、样式美化、特殊图形,把"画得出来"升级成"画得好"。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U