← 返回学习中心ARC LAB / LEARNING NOTES

Python 专区

Python Matplotlib

从 Figure 与 Axes 到多子图、坐标和导出,绘制可解释的图表。

展开本篇目录

一、为什么学习 Matplotlib?

Matplotlib 将数据映射为图形,适合实验结果、统计报告和可复现的图表。它的价值不只是“画出一张图”,还包括明确坐标、单位、样本量和导出方式。

先修 Python 与基本数组操作。路线:Figure/Axes → 常见图型 → 标签与图例 → 多子图 → 保存 → 解释结果。先画小样例,确认数据与坐标,再调整美观。

python -m pip install matplotlib numpy

二、Figure、Axes、Axis 分别是什么?

Figure 包含多个 Axes,每个 Axes 管理图形、横纵轴和标签

  • Figure 是整张画布,负责尺寸、布局和保存。
  • Axes 是一个绘图区,负责画曲线、设置标题和范围。
  • Axis 是坐标轴对象,负责刻度等细节。不要因为复数名字 Axes 就把它等同于所有横纵轴。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6,4))
ax.plot([1,2,3], [60,75,85], marker="o", label="Score")
ax.set(xlabel="Week", ylabel="Score (0-100)", title="Learning record")
ax.set_ylim(0,100)
ax.legend()
fig.tight_layout()
fig.savefig("score.png", dpi=160)
plt.close(fig)

建议优先使用 fig, ax 的显式接口,避免多张图时误把设置作用到“当前图”。

三、四种常见图型

同一组虚构数据的折线、柱状、散点和直方图,由脚本实际生成

问题 接口 输入含义
有序变化 ax.plot(x,y) x、y 成对,必要时先按 x 排序
类别比较 ax.bar(labels,values) 类别与数值一一对应
两变量关系 ax.scatter(x,y) 每个点是一对观测
数值分布 ax.hist(values,bins=...) bins 是分箱边界或数量

折线连接点会暗示顺序;类别无顺序时不要随意连线。散点显示相关趋势,不说明因果。直方图柱宽表示数值区间,普通柱状图柱子表示类别,两者不是一回事。

四、样式服务于信息

ax.plot(x, y, color="#1688b8", linewidth=2, marker="o", label="Group A")
ax.grid(axis="y", alpha=0.25)
ax.legend()

这里假设已有 x、y、ax。不要只用红绿区分组别,应同时使用线型、标记或直接文字标签。网格线用于辅助读数,过深会抢走数据的视觉重点。

label 设置图例文字,调用 legend() 才显示。标题说明“画什么”,坐标说明“量什么以及单位是什么”,正文说明“这些数据能支持什么结论”。

五、多子图与共享坐标

fig, axs = plt.subplots(1,2,figsize=(9,4),sharey=True,layout="constrained")
axs[0].plot([1,2,3],[60,70,80])
axs[1].plot([1,2,3],[65,75,85])
for ax in axs:
ax.set_ylim(0,100)
ax.set_xlabel("Week")
axs[0].set_ylabel("Score")
fig.savefig("comparison.png",dpi=160)
plt.close(fig)

axs 的形状依赖行列数量:一个子图时通常是单个 Axes,多行多列时通常是二维数组。可用 squeeze=False 明确保持二维结构。不要一边使用 constrained layout,一边反复手动覆盖所有边距;先选定布局策略。

六、坐标范围会改变读者的感受

相同 82 与 85 两个数值,零基线与截断纵轴产生不同视觉差异

两幅图数据完全相同。右图故意截断纵轴,用于说明可能夸大差异,不能作为没有说明的报告图。柱状图通常从零开始;折线图未必必须从零开始,但应清楚标注范围并解释选取理由。

对数坐标可用 ax.set_yscale("log"),但普通对数轴不能直接表达零和负值。不要为了“让图好看”把不合适的数据静默删除。

七、误差条、分布与样本量

fig, ax = plt.subplots()
ax.errorbar([1,2], [80,85], yerr=[3,5], fmt="o", capsize=4)
ax.set(xlabel="Group", ylabel="Score")
plt.close(fig)

必须说明 yerr 表示标准差、标准误还是置信区间,三者不是同一概念。不要把一批数随意标为“95% 置信区间”;也不要仅凭误差条重叠就下统计显著性结论。小样本建议展示个体点。

八、图片、色条与数值映射

import numpy as np
fig, ax = plt.subplots()
image = ax.imshow(np.arange(12).reshape(3,4), cmap="viridis")
fig.colorbar(image, ax=ax, label="Value")
fig.savefig("heatmap.png",dpi=160)
plt.close(fig)

对比两张热图时,颜色范围要一致,例如设置同样的 vmin 和 vmax。自动归一化可能让幅度不同的数据看起来同样鲜艳。显示 OpenCV 彩图前,通常需要 BGR→RGB 转换。

九、中文、负号与运行环境

Matplotlib 不保证系统已安装中文字体。应选择系统实际存在且有中文字符的字体,再通过 rcParams["font.sans-serif"] 配置;不能复制一个字体名就认为所有电脑都可用。

本篇配图用英文标签避免依赖额外字体,正文提供中文解释。无显示器服务器可在导入 pyplot 之前 设置:

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

Notebook 可内嵌显示,桌面脚本可 plt.show();保存导出时仍建议使用 fig.savefig。某些环境 show 之后当前图状态变化,先保存再显示更清楚。

十、保存与批量绘图

  • PNG 是位图,dpi 决定指定英寸尺寸下的像素数量。
  • SVG/PDF 常适合矢量线条和文字,但并非其中每个元素都是矢量,例如嵌入的照片。
  • 多次循环绘图后 plt.close(fig),防止保留大量画布占用内存。
  • transparent=True 输出透明背景前,应检查深浅背景都能读清楚。
fig.savefig("report.svg", bbox_inches="tight")

这行需在 Figure 尚存在时运行。报告中还应记录数据文件、清洗规则和绘图代码,而不只保存最终截图。

十一、完整实验与练习

下载 matplotlib_demo.py:

python matplotlib_demo.py --output results

生成本文两张真实结果图,数据为虚构示例。

  1. 给四个子图加样本量说明,检查每个坐标是否有单位。
  2. 把折线数据顺序打乱,比较不排序直接连接与按 x 排序的差异。
  3. 将直方图分箱从 5 改成 3,说明形状变化是否代表原始数据发生变化。
  4. 用同一份数据导出 PNG 和 SVG,放大观察线条和文件体积。
  5. 小项目:用自己的非敏感数据制作一张报告图,让同伴在不看代码的情况下解释变量、单位和结论边界。

常见排错: 图空白先检查数据和保存对象;中文方框检查字体;图例缺失检查 label/legend;轴标签被截断检查布局;内存持续增长检查 close。

十二、学习资料

← 继续探索学习路径反馈问题 ↗