大家好,我是你们的小帅学长。
很多同学画图时会把注意力放在颜色、线型、布局上,但真正让一张图“看起来像论文图”的,往往是你的文本系统。
你一定见过这些情况:
标题太大太抢、或者太小看不清;
注释一多就乱飞,重点反而看不出来;
公式写不出来,或者写出来很丑;
中英混排时:中文像“另一个宇宙”,英文像“另一个字体”;
单位、上下标、希腊字母、负号……各自为政。
这一篇我会把“论文图里的文本系统”拆成可操作的四块:
标题体系、注释体系、公式体系、中英混排体系。
你学会后,你的图会立刻从“能用”升级到“论文级”。
01.标题系统:别写成论文小节名,要写成“图的结论”
很多人标题写成:“Figure 1. Results” 或 “Model comparison”,这种标题在图上几乎没有信息价值。
我更推荐的标题写法是:标题尽量表达结论或信息点,而不是描述行为。
那标题字号怎么定?
一个简单的比例建议:标题 > 坐标轴标签 > 刻度,但不要差太多,差太多会“标题抢戏”。
02.注释系统:只标“关键点”,并且让它“对齐逻辑”
注释的本质不是“写满”,而是说明哪里是重点、为什么是重点。
三条实用规则:
注释数量越少越高级:最多 3–5 个关键注释;
注释位置要统一风格:尽量对齐、不要东一块西一块;
优先用“近距离解释”:注释尽量靠近对象,减少读者视线跳跃。
常见注释手段(按推荐顺序):
轻量文字标注;
箭头指向;
框选区域;
角标/编号。
03.公式系统:科研图的“高级感”很多来自正确的公式排版
Matplotlib 支持 LaTeX 风格的数学公式(mathtext)。
你不需要会完整 LaTeX,只要记住常见写法就够用。
常用公式写法速查:
上标:$x^2$
下标:$T_s$
希腊字母:$\alpha, \beta, \sigma$
分数:$\frac{a}{b}$
乘号:$\times$
单位:建议写成普通文本或公式内 \,控制空格
例如坐标轴写:
ax.set_ylabel(r"$T_s$ (K)")
小技巧:字符串前加 r(raw string)能避免反斜杠转义问题。
04.中英混排:让“中文像中文、英文像英文”,但风格统一
中英混排最大的问题是:中文字体不支持英文的字形风格,英文字体不支持中文。
结果就是:一张图里像两套系统拼在一起。
科研出图里更稳的做法是:用“字体回退(fallback)”机制实现“英文走 Times New Roman,中文走宋体(SimSun)”。
推荐的字体策略(稳、好维护):
英文/数字:Times New Roman
中文:SimSun(宋体)
公式(mathtext):强制 Times New Roman
负号:关闭 unicode 负号以兼容宋体
这样 Matplotlib 会优先用 Times New Roman 渲染英文字符,遇到 Times 不支持的中文字符时自动回退到宋体,从而实现同一张图中英混排稳定且统一。
05.直接上手:一份“文本系统示范模板”
下面这段代码做了四件事:
标题层级清晰;
注释对齐且不过量;
公式可读;
中英混排稳定(你可以按你电脑字体替换)。
import osimport numpy as npimport matplotlib as mplimport matplotlib.pyplot as pltfrom matplotlib import font_manager as fm# == 0) 显式注册字体(关键!解决方框)==def _try_add_font(font_full_path: str):if font_full_path and os.path.exists(font_full_path):try:fm.fontManager.addfont(font_full_path)except Exception:passWIN_FONTS = r"C:\Windows\Fonts"TIMES_TTF_CANDIDATES = [os.path.join(WIN_FONTS, "times.ttf"), # Times New Roman Regularos.path.join(WIN_FONTS, "timesbd.ttf"),os.path.join(WIN_FONTS, "timesi.ttf"),]SIMSUN_TTC_CANDIDATE = os.path.join(WIN_FONTS, "simsun.ttc") # 宋体for p in TIMES_TTF_CANDIDATES:_try_add_font(p)_try_add_font(SIMSUN_TTC_CANDIDATE)# == 1) 全局字体策略(英文优先 Times,中文回退 SimSun) ==# 关键点:font.family 直接给 “列表”,Matplotlib 会按顺序找字形并回退mpl.rcParams["font.family"] = ["Times New Roman", "SimSun"]# 数学公式统一 Times New Roman(避免公式风格跳变)mpl.rcParams["mathtext.fontset"] = "custom"mpl.rcParams["mathtext.rm"] = "Times New Roman"mpl.rcParams["mathtext.it"] = "Times New Roman:italic"mpl.rcParams["mathtext.bf"] = "Times New Roman:bold"# 负号稳定(配合中文字体常用)mpl.rcParams["axes.unicode_minus"] = False# ==2) 输出路径==OUT_DIR = r"D:\py_figs"os.makedirs(OUT_DIR, exist_ok=True)# ==3) 数据==x = np.linspace(0, 10, 200)y = np.sin(x) + 0.1 * np.random.randn(len(x))# ==4) 画图==fig, ax = plt.subplots(figsize=(6, 4))ax.plot(x, y, linewidth=2, label="Observation / 观测值")ax.set_title("中文标题:波形变化与关键点标注 (Waveform & Key Point)", fontsize=14)ax.set_xlabel("Time (day) / 时间(天)", fontsize=12)ax.set_ylabel("Tₛ (K)/温度", fontsize=12)idx = np.argmax(y)x0, y0 = x[idx], y[idx]ax.scatter([x0], [y0], s=40)ax.annotate("Peak / 峰值",xy=(x0, y0),xytext=(x0 - 0.3, y0 -0.2),arrowprops=dict(arrowstyle="->", lw=1),fontsize=11,)ax.legend(frameon=False)ax.grid(alpha=0.25)# == 5) 保存==out_path = os.path.join(OUT_DIR, "text_system_demo.jpg")fig.savefig(out_path, dpi=300, bbox_inches="tight")plt.close(fig)print("Saved:", out_path)

科研图的专业感,很大程度来自一套稳定的文本系统——标题、注释、公式、中英混排。
——期待你的关注——