Matplotlib 设置支持中文的默认字体
问题描述
python 3.7 使用 matplotlib 时汉字显示为方框,如下:
问题原因
matplotlib 使用的默认字体不支持中文,需要更换绘制字体。可以指定的字体能够在系统字体目录下找到,指定的字体名通常与字体文件名不同。
这里可以参考 别人总结的 Windows 字体名称
解决方案1
在 python 代码指定绘制汉字之前加入如下语句将本次绘制的字体更改为 黑体(SimHei),并取消使用 unicode 的负号,防止更改字体后负号显示方框:
from matplotlib import pyplot as plt
# 设置字体 显示汉字
plt.rcParams["font.sans-serif"] = "SimHei"
# 取消使用 unicode 的负号
plt.rcParams["axes.unicode_minus"] = False
这段代码在每次使用 matplotlib 时都需要添加,非常麻烦,下一个方案可以直接更换默认的字体,比该方案方便。
解决方案2
从上个方案可以看出 rcParams 是一个字典,储存了 matplotlib 绘制图表时候的一些基本配置,所以在每个 py 文件中修改 rcParams 无疑是非常低效的,不如直接修改 matplotlib 的代码。
通过搜寻查到了 rcParams 的默认初始值所在的文件,其路径为 python 安装路径中的 Lib\site-packages\matplotlib\rcsetup.py,打开文件找到约 962 行的 defaultParams 即为 rcParams 的默认初始值。
以黑体为例,更改 defaultParams 中的 ‘font.family’,向 ‘font.serif’ 与 ‘font.sans-serif’ 添加黑体,并将 ‘axes.unicode_minus’ 的第一项置为 False,如下:
defaultParams = {
...
'font.family': [['SimHei'], validate_stringlist],
...
'font.serif': [['SimHei', 'DejaVu Serif', 'Bitstream Vera Serif',
'Computer Modern Roman',
'New Century Schoolbook', 'Century Schoolbook L',
'Utopia', 'ITC Bookman', 'Bookman',
'Nimbus Roman No9 L', 'Times New Roman',
'Times', 'Palatino', 'Charter', 'serif'],
validate_stringlist],
'font.sans-serif': [['SimHei', 'DejaVu Sans', 'Bitstream Vera Sans',
'Computer Modern Sans Serif',
'Lucida Grande', 'Verdana', 'Geneva', 'Lucid',
'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'],
validate_stringlist],
...
'axes.unicode_minus': [False, validate_bool],
...
保存后即可使用 matplotlib 直接绘制汉字。
绘制效果如下:
百度一查全都是但自测无效的方案
在解决这个问题前先试过其它修改默认设置的方案,但在我的环境中试过了都没有效果。如果有心,可以试试方案是否有效。
使用如下代码打印出配置文件与字体缓存的路径:
import matplotlib as mpl
print(mpl.matplotlib_fname()) # 配置文件路径
print(mpl.get_configdir()) # 字体缓存路径
修改 matplotlib 下的配置文件 matplotlibrc
使用上述的方法找到 matplotlibrc 文件,打开,找到并修改如下:
...
#font.family : SimHei
...
#font.serif : SimHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
#font.sans-serif : SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
...
#axes.unicode_minus : False ## use unicode for the minus symbol
保存后从系统字体目录中将 ttf 格式的黑体字体复制至 mpl-data\fonts\ttf 目录中,再使用 matplotlib 尝试绘制汉字。
删除 matplotlib 建立的字体缓存
使用上述方法找到 matplotlib 字体缓存目录,按之前的方式修改 fontList.json 文件,或在更改 matplotlibrc 文件后直接删除 fontList.json 文件,再使用 matplotlib 尝试绘制汉字。