Matplotlib缺少中文字体的修复

现象

Python运行Matplotlib库显示中文报错

1
2
Font family ['sans-serif'] not found.Falling back to DejaVu Sans
...

修复方法(Linux)

  1. 寻找相应字体,比如SimHei.ttf(Windows自带)

  2. 将字体文件放到/usr/share/fonts/truetype/目录或~/.local/share/fonts/

  3. 运行(可能需要sudo

    fc-cache -f -v

    重建系统字体缓存

  4. 删除matplotlib缓存
    python执行

    1
    2
    3
    import matplotlib
    print(matplotlib.get_cachedir())
    # '~/.cache/matplotlib'

    删除该目录

    rm -rf ~/.cache/matplotlib
  5. 重新测试

永久修复(Windows)

  1. 安装字体到Windows
    打开C:\Windows\Fonts,确保拥有黑体SimHei.ttf,Windows自带)或Arial Unicode MS(需要自行安装)。

  2. 创建Matplotlib配置文件
    查找Matplotlib文件夹:运行

    1
    2
    3
    import matplotlib
    print(matplotlib.get_data_path())
    # <PythonDir>\lib\site-packages\matplotlib\mpl-data

    matplotlibrc复制到%USERPROFILE%\.matplotlib\3

    不要修改<PythonDir>\lib\site-packages\matplotlib\mpl-data\matplotlibrc,[1-2]中描述的是错误用法。

  3. 修改Matplotlib配置文件
    打开%USERPROFILE%\.matplotlib\matplotlibrc文件,更新如下配置:

    matplotlibrc
    1
    2
    3
    4
    5
    font.family: sans-serif
    # 将字体名追加在开头
    font.sans-serif: SimHei, ...
    axes.unicode_minus: False
    # 注:黑体没有unicode负号,因此`axes.unicode_minus`必须要设置为`False`

    经测试Arial Unicode MS也是可以用的

    matplotlibrc
    1
    2
    3
    4
    font.family: sans-serif
    font.sans-serif: Arial Unicode MS, ...
    axes.unicode_minus: True
    # 注:Arial Unicode MS符号全,`axes.unicode_minus`可以设置为`True`

    经测试,font.sans-serif填入的是字体文件内部记录的字体名,而非文件名。

  4. 重新测试

临时修复(Windows)

  1. 复制字体同上

  2. 在代码中修改font.sans-serifaxes.unicode_minus配置,内容同上

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import matplotlib.pyplot as plt

    # 黑体:
    if not 'SimHei' in plt.rcParams['font.sans-serif']:
    plt.rcParams['font.sans-serif'].insert(0, 'SimHei')
    plt.rcParams['axes.unicode_minus'] = False

    # Arial Unicode MS
    if not 'Arial Unicode MS' in plt.rcParams['font.sans-serif']:
    plt.rcParams['font.sans-serif'].insert(0, 'Arial Unicode MS')
  3. 重新测试

参考

  1. Python matplotlib对中文的支持(Font family [‘sans-serif‘] not found.Falling back to DejaVu Sans)
  2. matplotlib中文乱码的两种解决方案
  3. The matplotlibrc file — Matplotlib documentation