Skip to content
YIZE
← 笔记Notes2026.08.30 · 2 分钟min

克制的画图方式,或者:一个我反复在用的 matplotlib 样式文件Plotting with restraint, or: a matplotlib style file I reuse

Plotting with restraint, or: a matplotlib style file I reuse克制的画图方式,或者:一个我反复在用的 matplotlib 样式文件

编程Programming笔记Note 04

论文里的图大多比它们需要的更难看,而修法通常是删而不是加。这是我用的样式表。

Most figures in scientific papers are worse than they need to be, and the fix is usually deletion rather than decoration. Here is the style sheet I use.

  • python
  • matplotlib
  • visualization
目录Contents

一张图只有一个任务:让一个比较变得看得见。凡是不帮这件事的东西都是噪声,而默认设置里大部分都是噪声。

我删掉的

  • 网格线。 一条网格线就是一根没标出来的坐标轴。读者要么是在从图上读数,那他需要的是一张表;要么是在读一个比较,那网格线就是在和数据抢。两种情况都不该留。
  • 上方与右侧的边框。 两条不携带任何信息的线。
  • 能直接标注时就不放图例。 如果一条曲线可以就地标注,那就标注,把图例整块去掉。
  • 为了好看而用颜色。 类别在五类以内时,先用位置和线型。

样式表

# figures/style.py — 项目里每个绘图脚本都 import 这个文件
import matplotlib as mpl

PAPER = "#faf8f4"
INK = "#1b1a17"
INK_2 = "#56534b"
RULE = "#e3ded3"
ACCENT = "#9e2b25"

mpl.rcParams.update(
    {
        "figure.facecolor": PAPER,
        "axes.facecolor": PAPER,
        "savefig.facecolor": PAPER,
        # 字体大小:把字号调对,比把图放大有用
        "font.size": 9,
        "axes.titlesize": 9,
        "axes.labelsize": 9,
        "legend.fontsize": 8,
        "xtick.labelsize": 8,
        "ytick.labelsize": 8,
        # 墨色与细线
        "text.color": INK,
        "axes.labelcolor": INK,
        "axes.edgecolor": RULE,
        "xtick.color": INK_2,
        "ytick.color": INK_2,
        "axes.linewidth": 0.8,
        "xtick.major.width": 0.8,
        "ytick.major.width": 0.8,
        "xtick.major.size": 3,
        "ytick.major.size": 3,
        "grid": False,
        # 只留两条边框,而且只在它有意义的方向上留
        "axes.spines.top": False,
        "axes.spines.right": False,
        # 线:在印刷尺寸下读得清,且不是每个点都放标记
        "lines.linewidth": 1.4,
        "lines.markersize": 3.5,
        "legend.frameon": False,
    }
)

# 一个短色板,转成灰度也能分清。
PALETTE = [INK, ACCENT, "#4a6fa5", "#1f6f54", "#8a5a1a"]

保存前我会做的检查

  1. 转成灰度。那个比较还读得出来吗?
  2. 缩到它将来被印刷时的宽度。标签还认得出吗?
  3. 把图例遮住。你还分得清哪条线是哪条吗?
  4. 问一句:如果再少一个元素,这张图会变成什么样?然后把它删掉。

第四步是最常让图变好的那一步,也是没有人做的那一步。

归档于 编程 · 2026.08.30

目录Contents

A figure has one job: to make a comparison visible. Everything that does not help do that is noise, and most of the defaults are noise.

What I remove

  • Grids. A gridline is an unlabelled axis. Either the reader is reading values off the plot, in which case they need a table, or they are reading a comparison, in which case the gridline is competing with the data.
  • Top and right spines. Two lines that carry no information.
  • Legends where a label fits. If a series can be labelled directly, do that and drop the legend entirely.
  • Colour for its own sake. With fewer than about five categories, use position and line style first.

The style sheet

# figures/style.py — imported by every plotting script in a project
import matplotlib as mpl

PAPER = "#faf8f4"
INK = "#1b1a17"
INK_2 = "#56534b"
RULE = "#e3ded3"
ACCENT = "#9e2b25"

mpl.rcParams.update(
    {
        "figure.facecolor": PAPER,
        "axes.facecolor": PAPER,
        "savefig.facecolor": PAPER,
        # Typography: a real font size beats a large figure.
        "font.size": 9,
        "axes.titlesize": 9,
        "axes.labelsize": 9,
        "legend.fontsize": 8,
        "xtick.labelsize": 8,
        "ytick.labelsize": 8,
        # Ink and rules
        "text.color": INK,
        "axes.labelcolor": INK,
        "axes.edgecolor": RULE,
        "xtick.color": INK_2,
        "ytick.color": INK_2,
        "axes.linewidth": 0.8,
        "xtick.major.width": 0.8,
        "ytick.major.width": 0.8,
        "xtick.major.size": 3,
        "ytick.major.size": 3,
        "grid": False,
        # Only two spines, and only where they mean something
        "axes.spines.top": False,
        "axes.spines.right": False,
        # Lines: readable at print size, no markers on every point
        "lines.linewidth": 1.4,
        "lines.markersize": 3.5,
        "legend.frameon": False,
    }
)

# A short palette that survives greyscale printing.
PALETTE = [INK, ACCENT, "#4a6fa5", "#1f6f54", "#8a5a1a"]

The check I run before saving

  1. Convert to greyscale. Is the comparison still readable?
  2. Shrink to the width it will be printed at. Are the labels still legible?
  3. Cover the legend. Can you still tell which series is which?
  4. Ask what the figure would look like with one fewer element. Delete it.

Step four is the one that improves figures most often, and it is the one nobody does.

Filed under Programming · 2026.08.30