Matplotlib 速查表
最后更新
画布与坐标系
Figure(画布)是整张图,Axes(坐标系)是其中的一个图表,下面几乎每个调用都是 ax 上的方法。
| 操作 | 代码 |
|---|---|
| 导入 pyplot | import matplotlib.pyplot as plt |
| 一张画布,一个图表 | fig, ax = plt.subplots() |
| 设置尺寸(英寸) | fig, ax = plt.subplots(figsize=(8, 4)) |
| 在坐标系上绘图 | ax.plot(x, y) |
| 显示图形 | plt.show() |
| 保存为清晰的 PNG | fig.savefig("chart.png", dpi=150, bbox_inches="tight") |
| 保存为矢量图 | fig.savefig("chart.svg"), fig.savefig("chart.pdf") |
| 透明背景 | fig.savefig("chart.png", transparent=True) |
| 关闭画布以释放内存 | plt.close(fig) |
| 用 pyplot 快速画一张图 | plt.plot(x, y)
plt.title("Quick look")
plt.show() |
图表类型
| 操作 | 代码 |
|---|---|
| 折线图 | ax.plot(x, y) |
| 散点图 | ax.scatter(x, y, s=20, alpha=0.7) |
| 按数值着色的散点图,带颜色条 | points = ax.scatter(x, y, c=y, cmap="viridis")
fig.colorbar(points, ax=ax) |
| 柱状图 | ax.bar(cats, a) |
| 水平条形图 | ax.barh(cats, a) |
| 堆叠柱状图 | ax.bar(cats, a, label="2025")
ax.bar(cats, b, bottom=a, label="2026") |
| 分组柱状图 | pos = np.arange(len(cats))
ax.bar(pos - 0.2, a, width=0.4)
ax.bar(pos + 0.2, b, width=0.4)
ax.set_xticks(pos, labels=cats) |
| 直方图 | ax.hist(data, bins=30) |
| 箱线图 | ax.boxplot([data, data * 2], tick_labels=["A", "B"]) |
| 小提琴图 | ax.violinplot([data, data * 2]) |
| 饼图 | ax.pie([40, 35, 25], labels=cats, autopct="%1.0f%%") |
| 两条曲线之间的填充带 | ax.fill_between(x, y - 0.2, y + 0.2, alpha=0.3) |
| 误差棒 | ax.errorbar([1, 2, 3], [4, 5, 3], yerr=[0.5, 0.3, 0.6], fmt="o", capsize=4) |
| 阶梯图 | ax.step(x, y, where="mid") |
| 二维数组热力图 | image = ax.imshow(np.random.default_rng(0).random((5, 5)), cmap="magma")
fig.colorbar(image, ax=ax) |
| 填充等高线图 | X, Y = np.meshgrid(x, x)
ax.contourf(X, Y, np.sin(X) * np.cos(Y), levels=20) |
| 大量数据点的密度图 | ax.hexbin(data, data + np.random.default_rng(1).normal(size=200), gridsize=20) |
| 水平或垂直参考线 | ax.axhline(0, color="gray", linestyle="--"), ax.axvline(5) |
| 给一段区间加阴影 | ax.axvspan(2, 4, alpha=0.2) |
线条、标记与颜色
| 操作 | 代码 |
|---|---|
| 颜色、线宽和线型 | ax.plot(x, y, color="tab:red", linewidth=2, linestyle="--") |
| 在数据点上加标记 | ax.plot(x, y, marker="o", markersize=4) |
| 简写格式字符串 | ax.plot(x, y, "g--o") |
| 透明度 | ax.plot(x, y, alpha=0.5) |
| 线型 | "-", "--", "-.", ":" |
| 标记代码 | "o", "s", "^", "x", ".", "*" |
| 指定颜色的几种方式 | "tab:blue", "C1", "#1f77b4", (0.2, 0.4, 0.6) |
| 从颜色映射中取 n 种颜色 | colors = plt.colormaps["viridis"](np.linspace(0, 1, 5)) |
| 自定义颜色循环 | ax.set_prop_cycle(color=["#0b7285", "#e8590c", "#5f3dc4"]) |
| 带描边和填充图案的柱子 | ax.bar(cats, a, color="white", edgecolor="black", hatch="//") |
标题、标签与图例
| 操作 | 代码 |
|---|---|
| 标题和坐标轴标签 | ax.set_title("Sales"), ax.set_xlabel("Month"), ax.set_ylabel("EUR") |
| 一次设置全部 | ax.set(title="Sales", xlabel="Month", ylabel="EUR") |
| 根据线条的 label 生成图例 | ax.plot(x, y, label="sin")
ax.legend() |
| 图例位置和列数 | ax.legend(loc="upper right", ncols=2, frameon=False) |
| 把图例放在图表外面 | ax.legend(loc="center left", bbox_to_anchor=(1, 0.5)) |
| 在数据坐标处添加文字 | ax.text(5, 0.5, "note") |
| 带箭头的注释 | ax.annotate("peak", xy=(1.57, 1), xytext=(3, 1.2), arrowprops=dict(arrowstyle="->")) |
| 在柱子上显示数值 | bars = ax.bar(cats, a)
ax.bar_label(bars) |
| 整张画布的总标题 | fig.suptitle("Q1 report") |
| 在标签中使用数学公式 | ax.set_xlabel(r"$\alpha$ (rad)") |
坐标轴、刻度与比例
| 操作 | 代码 |
|---|---|
| 坐标轴范围 | ax.set_xlim(0, 10), ax.set_ylim(bottom=0) |
| 对数坐标 | ax.set_yscale("log") |
| 指定刻度及其标签 | ax.set_xticks([0, 5, 10], labels=["start", "middle", "end"]) |
| 旋转刻度标签 | ax.tick_params(axis="x", labelrotation=45) |
| 网格线 | ax.grid(True, alpha=0.3) |
| 百分比坐标轴 | from matplotlib.ticker import PercentFormatter
ax.yaxis.set_major_formatter(PercentFormatter(1.0)) |
| 千位分隔符 | ax.yaxis.set_major_formatter("{x:,.0f}") |
| 隐藏上边框和右边框 | ax.spines[["top", "right"]].set_visible(False) |
| 右侧第二条 y 轴 | ax2 = ax.twinx()
ax2.plot(x, y * 100, color="tab:orange") |
| 两个轴使用相同比例 | ax.set_aspect("equal") |
| 翻转坐标轴 | ax.invert_yaxis() |
| 完全隐藏坐标轴 | ax.axis("off") |
| 让日期标签更易读 | fig.autofmt_xdate() |
子图与布局
plt.subplots(rows, cols) 返回一个由坐标系组成的 NumPy 数组,像数组一样用索引访问即可。
| 操作 | 代码 |
|---|---|
| 子图网格 | fig, axs = plt.subplots(2, 2, figsize=(8, 6)) |
| 在其中一个子图上绘图 | axs[0, 1].plot(x, y) |
| 遍历所有子图 | for ax in axs.flat:
ax.grid(True) |
| 子图之间共享坐标轴 | fig, axs = plt.subplots(1, 3, sharey=True) |
| 自动调整间距,避免重叠 | fig, axs = plt.subplots(2, 2, layout="constrained") |
| 绘图后修复重叠 | fig.tight_layout() |
| 不同宽度的列 | fig, axs = plt.subplots(1, 2, width_ratios=[3, 1]) |
| 带宽面板的命名布局 | fig, axd = plt.subplot_mosaic([["top", "top"], ["left", "right"]])
axd["top"].plot(x, y) |
| 图中嵌入小图 | inset = ax.inset_axes([0.6, 0.6, 0.35, 0.35]) |
| 隐藏空白面板 | axs[0].axis("off") |
样式与默认设置
| 操作 | 代码 |
|---|---|
| 使用内置样式 | plt.style.use("ggplot") |
| 列出所有样式 | plt.style.available |
| 不装 seaborn 也能用 seaborn 风格 | plt.style.use("seaborn-v0_8-whitegrid") |
| 只对一张图使用某个样式 | with plt.style.context("dark_background"):
fig, ax = plt.subplots() |
| 默认字号 | plt.rcParams["font.size"] = 12 |
| 默认画布尺寸和分辨率 | plt.rcParams["figure.figsize"] = (8, 4), plt.rcParams["figure.dpi"] = 120 |
| 恢复默认设置 | plt.style.use("default") |
| 常用颜色映射:顺序型、发散型、灰度 | "viridis", "coolwarm", "Greys" |
用 pandas 绘图
pandas 底层用 Matplotlib 绘图。传入 ax= 可以画到你自己的坐标系上,也可以保留 pandas 返回的 ax 继续调整。
| 操作 | 代码 |
|---|---|
| 把 DataFrame 的列画到你的坐标系上 | df.plot(x="month", y="sales", ax=ax) |
| 分组汇总结果的柱状图 | df.groupby("city")["sales"].sum().plot.bar(ax=ax) |
| 继续美化 pandas 画出的图 | ax = df.plot(x="month", y="sales")
ax.set_title("Sales") |
| 直接把列交给 Matplotlib | ax.plot(df["month"], df["sales"]) |
Matplotlib 3.11:旧写法与现在的写法
从旧教程复制来的代码在 Matplotlib 3.11 中可能报错或产生警告,请改用 Matplotlib 3.11 一列中的写法。
| 操作 | Matplotlib 3.11 | 旧写法 |
|---|---|---|
| 箱线图标签 | ax.boxplot([data, data * 2], tick_labels=["A", "B"]) | labels=["A", "B"] |
| 水平箱线图或小提琴图 | ax.boxplot(data, orientation="horizontal") | vert=False |
| 获取颜色映射 | plt.colormaps["viridis"] | plt.cm.get_cmap("viridis") |
| seaborn 样式 | plt.style.use("seaborn-v0_8") | plt.style.use("seaborn") |
把数据画成清晰图表所需的 Matplotlib 代码,按任务分组:画布与坐标系、图表类型、线条与颜色、标题与图例、坐标轴与刻度、子图与布局、样式,以及用 pandas 绘图。每一行都是一段可以直接粘贴的短代码,再配一句话说明它的作用。
这里全部采用面向对象的写法(先 fig, ax = plt.subplots(),再调用 ax 上的方法),基于 Coddy 运行的 Matplotlib 3.11 编写。boxplot 中的 labels= 这类旧写法只出现在最后一张表里,旁边写明了现在该怎么写。示例使用 x = np.linspace(0, 10, 50)、y = np.sin(x),以及一组名为 data 的正态分布样本。还不熟悉 Python 本身?先看 Python 速查表,再把 pandas、NumPy 和 scikit-learn 速查表放在手边一起用。
Matplotlib 速查表常见问题
这份 Matplotlib 速查表免费吗?
免费。这份 Matplotlib 速查表完全免费,无需注册。把它加入书签,或者在浏览器里打印成 PDF,需要查图例、子图网格或颜色条的写法时随时回来看。
plt 和 ax 有什么区别?
plt.plot() 画在当前的坐标系上,只画一张图时很方便。fig, ax = plt.subplots() 把画布和坐标系作为对象交给你,ax.plot() 就总能画在你想要的位置。凡是有多个图表的情况,以及需要长期保留的代码,都建议用 ax 写法。怎么修改图形尺寸?
figsize:fig, ax = plt.subplots(figsize=(10, 5))。要修改所有图形的默认尺寸,可以设置 plt.rcParams["figure.figsize"] = (10, 5)。保存出的文件像素尺寸等于 figsize 乘以 dpi。怎么保存高分辨率的图表?
fig.savefig("chart.png", dpi=300, bbox_inches="tight")。dpi 越高,PNG 越清晰,bbox_inches="tight" 会裁掉多余的空白边距。用于打印或幻灯片时,可以保存为 SVG 或 PDF,任意缩放都不会模糊。为什么子图的标题和标签会重叠?
layout="constrained",例如 plt.subplots(2, 2, layout="constrained"),Matplotlib 会自动为标题、标签和颜色条留出空间。对于已经画好的画布,在绘图之后调用 fig.tight_layout()。这份速查表对应哪个 Matplotlib 版本?
boxplot 中的 labels=(现在是 tick_labels=)和 plt.cm.get_cmap(现在是 plt.colormaps[...]),都列在最后一张表里,旁边写明了现在的写法。