0. 问题
进行科研绘图时,常常需要使用Times New Roman+宋体混排,但Matplotlib无法兼顾两种字体。设置成Times New Roman时,中文字体显示为方块,如图1所示;采用宋体时,数字与字母无法显示成Times New Roman字形,如图2所示。目前Matplotlib还没有较好的方式对中英文字体进行分别设置。
plt.rcParams['font.sans-serif'] = 'times new roman'
x = np.linspace(0, 2*np.pi, 200)
y = np.sin(2*np.pi*x)
fig, ax = plt.subplots(figsize=(8, 2))
ax.plot(x, y)
ax.set_xlabel('时间 (t)')
plt.rcParams['font.sans-serif'] = 'simsun'
x = np.linspace(0, 2*np.pi, 200)
y = np.sin(2*np.pi*x)
fig, ax = plt.subplots(figsize=(8, 2))
ax.plot(x, y, 'r')
ax.set_xlabel('时间 (t)')
1. 合并Times New Roman与宋体
本文采用的是将Times New Roman与宋体合并成新字体的方式。合成字体的字母与数字为Times New Roman,中文为宋体。
字体合并工具:
① Warcraft Font Merger,魔兽世界字体合并/补全工具GitHub – nowar-fonts/Warcraft-Font-Merger: Warcraft Font Merger,魔兽世界字体合并/补全工具。
② Fontforge
FontForge Open Source Font Editor
其实Fontforge本身就可以完成字体合并、字体重命名等全部功能,建议读者参考并尝试《完美字体合并教程 / 中英文字体合并 / 解决字间距过大或异常 – 知乎》相关流程。但我在自己电脑上执行合并时程序崩溃。无奈只能用Warcraft Font Merger先进行合并,再用Fontforge重命名字体。,如果Fontforge同样崩溃再退而求其次,请按照以下流程。
本文介绍的字体合并流程为:① Warcraft Font Merger → ② Fontforge
① Warcraft Font Merger
从Windows Font字体文件夹中找到宋体和Times New Roman字体文件。按照官方教程中的说明,框选中文、英文字体,然后点住英文字体移动到合并补全.bat上。等待1min左右,得到字体out.ttf.
② Fontforge
Warcraft Font Merger合并完的字体名是“out.ttf”,如果不介意的话,也可以安装直接用。如果犯强迫症需要改名字,可以通过Fontforge进一步处理。
首先用Fontforge打开out.ttf
点击Element->Font Info…
打开之后能看到字体实际Fontname/Famliy Name等等,修改成想要的名称。
点击OK,弹出提示需要修改UniqueId,点击Change。
选择File -> Gnerate Fonts… 生成字体,弹出对话框,点击Generate。
点击生成后,经过几分钟,会弹出错误提示,笔者这里不太懂字体相关的问题。强行Generate,生成的字体好像也没什么问题。
生成字体后,安装即可。
2. 结果
将上述代码中字体改为TimesNewRomanSimSun后,中英文均正常显示,中文为宋体,英文与数字为Times New Roman。
plt.rcParams['font.sans-serif'] = 'TimesNewRomanSimSun'
对于其他有类似需求的地方,也可以采用合成字体的方法。比如MATLAB命令窗口这种不支持多字体设置的应用中,使用Cascadia、Monaco等宽字体时,中文显示为方框。也可以自己合成字体来使用。