matplotlib 中的字体 fallback
matplotlib 的默认字体不支持中文。为了支持中文内容,我们可以选择将默认字体切换为中文字体,如宋体:
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimSun'
但是,宋体的英文和数字字符不太美观。很多时候我们需要中文使用宋体、英文使用 Times New Roman 字体。在旧版的 matplotlib 中,字体是没有 fallback 功能的。matplotlib 确实可以定义一组默认字体,但在使用字体时,matplotlib 遵循以下规则:
- 从默认字体列表中选择第一个字体,查找系统中是否安装有该字体。
- 如果找到,则使用该字体。遇到该字体不包含的字符时,用框框代替,而不是选择下一个字体。
- 如果没找到,则查找默认字体列表中的第二个字体。
对中英字体混排的需求导致大量相关教程和博客的出现,这里有一些我找到的文章:
- https://zhuanlan.zhihu.com/p/118601703
- https://blog.csdn.net/weixin_43958105/article/details/123816865
- https://zhuanlan.zhihu.com/p/501395717
大致思想都是:默认字体用宋体,涉及字母和符号的部分,用 LaTeX 来写,因为 matplotlib 允许存在一个独立的 LaTeX 字体。只要我们将 LaTeX 字体设置为和 Times New Roman 类似的字体,并取消公式中默认的斜体样式,就可以获得以假乱真的效果。此外文 3 还提到可以用工具组合字体。
然而,matplotlib 从 3.6.0 版本开始支持 fallback 字体。这意味着当使用当前字体找不到对应的字符时,matplotlib 会自动到字体列表的下一个字体中查找字符。所以如果你的 matplotlib 版本 \(\geq\) 3.6.0,那么你可以用
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Times New Roman', 'SimSun']
来简单地完成中英文字体的混排。
一些有帮助的链接: