Matplotlib中文乱码的根本原因是默认字体不支持中文且字体查找机制跳过系统中文字体,同时mathtext将减号映射为U+2212而中文字体通常不覆盖该码位。

matplotlib 中文乱码的根本原因是什么
Matplotlib 默认字体不支持中文,且其字体查找机制会跳过系统中已安装的中文字体;同时,默认字体(如 DejaVu Sans)不包含中文字符映射,导致显示为方块。负号(-)显示为方块或空格,是因为 Matplotlib 将减号当作数学符号,启用 mathtext 渲染时默认使用 STIX 或 Computer Modern 字体——它们也不含中文,且对 ASCII 减号做了 Unicode 映射替换(变成 U+2212 MINUS SIGN),而中文字体通常不覆盖该码位。
临时解决:每次绘图前手动设置字体
这不是永久方案,但能快速验证是否字体路径/名称正确:
- 先查系统中可用的中文字体:
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'),然后用 matplotlib.font_manager.FontProperties 加载
- 更常用的是直接指定字体名(注意不是文件名):
plt.rcParams['font.sans-serif'] = ['SimHei', 'KaiTi', 'Microsoft YaHei', 'AR PL UKai CN']
- 必须关闭无衬线字体的数学渲染干扰:
plt.rcParams['axes.unicode_minus'] = False(否则负号仍变方块)
示例:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot([1, 2, 3], [-10, -5, 0])
plt.title('温度变化趋势')
plt.show()
永久配置:修改 matplotlib 配置文件 matplotlibrc
永久生效的关键是改对文件——不是 Python site-packages 下的模板,而是用户级配置目录下的实际生效文件:
- 运行
matplotlib.get_configdir() 查到路径(如 ~/.matplotlib 或 C:\Users\XXX\.matplotlib)
- 在该目录下新建或编辑
matplotlibrc(无后缀),添加三行:
font.sans-serif: Microsoft YaHei, SimHei, KaiTi, sans-serif
axes.unicode_minus: False
axes.titlesize: medium
注意:font.sans-serif 值列表里**不能有空格分隔的逗号以外的空白**(如 Microsoft YaHei , SimHei 会失败);顺序代表 fallback 优先级,建议把最稳定、系统必有的字体放前面。
Windows / macOS / Linux 各平台字体名差异与避坑点
不同系统预装字体名不一致,硬写死一个名字容易失效:
- Windows 推荐用:
Microsoft YaHei(微软雅黑)、SimHei(黑体),避免用 NSimSun(新宋体)——它不支持粗体变体,title 加粗会回退失败
- macOS 可用:
Heiti SC(黑体-简)、Hiragino Sans GB,但需确认是否在 findSystemFonts() 结果里出现(某些版本需手动安装)
- Linux(如 Ubuntu)常见问题:系统自带的
Noto Sans CJK SC 在 matplotlib 中注册名为 Noto Sans CJK JP 或 AR PL UMing CN,建议先运行 fc-list :lang=zh 查真实名称
- 所有平台都建议加一个兜底项
sans-serif,防止前面全失效时至少不报错
改完配置后,**必须重启 Python 解释器或 Jupyter kernel**,因为 matplotlib.rcParams 在模块导入时就已初始化完毕,运行时改 matplotlibrc 文件不会自动重载。
字体配置看着简单,但实际生效依赖字体文件存在、名称拼写精确、fallback 顺序合理、以及 mathtext 开关匹配——漏掉任意一环,中文或负号就可能突然“消失”。
- 先查系统中可用的中文字体:
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'),然后用matplotlib.font_manager.FontProperties加载 - 更常用的是直接指定字体名(注意不是文件名):
plt.rcParams['font.sans-serif'] = ['SimHei', 'KaiTi', 'Microsoft YaHei', 'AR PL UKai CN'] - 必须关闭无衬线字体的数学渲染干扰:
plt.rcParams['axes.unicode_minus'] = False(否则负号仍变方块)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot([1, 2, 3], [-10, -5, 0])
plt.title('温度变化趋势')
plt.show()
永久配置:修改 matplotlib 配置文件 matplotlibrc
永久生效的关键是改对文件——不是 Python site-packages 下的模板,而是用户级配置目录下的实际生效文件:
- 运行
matplotlib.get_configdir() 查到路径(如 ~/.matplotlib 或 C:\Users\XXX\.matplotlib)
- 在该目录下新建或编辑
matplotlibrc(无后缀),添加三行:
font.sans-serif: Microsoft YaHei, SimHei, KaiTi, sans-serif
axes.unicode_minus: False
axes.titlesize: medium
注意:font.sans-serif 值列表里**不能有空格分隔的逗号以外的空白**(如 Microsoft YaHei , SimHei 会失败);顺序代表 fallback 优先级,建议把最稳定、系统必有的字体放前面。
Windows / macOS / Linux 各平台字体名差异与避坑点
不同系统预装字体名不一致,硬写死一个名字容易失效:
- Windows 推荐用:
Microsoft YaHei(微软雅黑)、SimHei(黑体),避免用 NSimSun(新宋体)——它不支持粗体变体,title 加粗会回退失败
- macOS 可用:
Heiti SC(黑体-简)、Hiragino Sans GB,但需确认是否在 findSystemFonts() 结果里出现(某些版本需手动安装)
- Linux(如 Ubuntu)常见问题:系统自带的
Noto Sans CJK SC 在 matplotlib 中注册名为 Noto Sans CJK JP 或 AR PL UMing CN,建议先运行 fc-list :lang=zh 查真实名称
- 所有平台都建议加一个兜底项
sans-serif,防止前面全失效时至少不报错
改完配置后,**必须重启 Python 解释器或 Jupyter kernel**,因为 matplotlib.rcParams 在模块导入时就已初始化完毕,运行时改 matplotlibrc 文件不会自动重载。
字体配置看着简单,但实际生效依赖字体文件存在、名称拼写精确、fallback 顺序合理、以及 mathtext 开关匹配——漏掉任意一环,中文或负号就可能突然“消失”。
matplotlib.get_configdir() 查到路径(如 ~/.matplotlib 或 C:\Users\XXX\.matplotlib)matplotlibrc(无后缀),添加三行:- Windows 推荐用:
Microsoft YaHei(微软雅黑)、SimHei(黑体),避免用NSimSun(新宋体)——它不支持粗体变体,title加粗会回退失败 - macOS 可用:
Heiti SC(黑体-简)、Hiragino Sans GB,但需确认是否在findSystemFonts()结果里出现(某些版本需手动安装) - Linux(如 Ubuntu)常见问题:系统自带的
Noto Sans CJK SC在 matplotlib 中注册名为Noto Sans CJK JP或AR PL UMing CN,建议先运行fc-list :lang=zh查真实名称 - 所有平台都建议加一个兜底项
sans-serif,防止前面全失效时至少不报错
matplotlib.rcParams 在模块导入时就已初始化完毕,运行时改 matplotlibrc 文件不会自动重载。
字体配置看着简单,但实际生效依赖字体文件存在、名称拼写精确、fallback 顺序合理、以及 mathtext 开关匹配——漏掉任意一环,中文或负号就可能突然“消失”。










