根本原因是Matplotlib默认不支持中文字体,未指定可用中文字体路径且字体缓存未清除,导致渲染时回退至无中文的DejaVu Sans而显示方块。

Matplotlib绘图时标题/坐标轴文字显示为方块,根本原因是什么 Matplotlib默认不支持中文字体,它会尝试用无衬线西文字体(如DejaVu Sans)渲染中文字符,而该字体不含中文字符集,于是回退成空心方块(□)或 tofu 字符。这不是编码问题(UTF-8 没错),而是**字体缺失 + 未显式指定可用中文字体路径**导致的渲染失败。
常见错误现象包括:plt.title("中文标题")、plt.xlabel("时间")、ax.set_ylabel("数值") 全部显示为方块;调用 plt.show() 后控制台可能打印警告:findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
最可靠的方法:直接修改 Matplotlib 的 font.sans-serif 配置并禁用字体缓存
手动指定系统已安装的中文字体(如 SimHei、Noto Sans CJK SC、Microsoft YaHei),并强制 Matplotlib 重新加载配置。关键点在于:**必须清除字体缓存,否则新配置不生效**。
操作步骤如下:
- 运行
import matplotlib; print(matplotlib.matplotlib_fname())查看当前配置文件路径(通常是.../matplotlib/mpl-data/matplotlibrc) - 打开该
matplotlibrc文件,找到font.sans-serif行,将其修改为(以 Windows 中的微软雅黑为例):font.sans-serif: Microsoft YaHei, SimHei, Noto Sans CJK SC, sans-serif
- 删除 Matplotlib 字体缓存目录:
import matplotlib; print(matplotlib.get_cachedir()),然后彻底删除该路径下所有文件(尤其是fontlist-*.json) - 重启 Python 解释器(或 kernel),再运行绘图代码
注意:Linux/macOS 用户需确认系统已安装对应中文字体(如 Ubuntu 安装 fonts-wqy-zenhei),macOS 可用 STHeiti 或 Heiti SC。
临时生效但易出错的写法:plt.rcParams 设置 vs matplotlib.rc
很多人习惯在脚本开头写:
plt.rcParams['font.sans-serif'] = ['SimHei', 'FangSong']<br>plt.rcParams['axes.unicode_minus'] = False
这能临时解决,但有明显缺陷:
立即学习“Python免费学习笔记(深入)”;
- 只对当前脚本有效,不改变全局配置,换一个脚本还得重复写
- 如果字体名拼错(比如写成
'Simhei'而非'SimHei'),Matplotlib 不报错,但静默失效 -
plt.rcParams设置后,若之前已导入pyplot并触发过字体查找,缓存可能已固化,导致设置无效 -
axes.unicode_minus=False是必须加的,否则负号(−)会显示为减号(–)或乱码
更稳妥的临时写法是把字体设置放在 import matplotlib.pyplot as plt 之后、任何绘图命令之前,并确保字体名与系统实际注册名一致(可用 matplotlib.font_manager.findSystemFonts() 查看)。
验证是否真正生效:用 matplotlib.font_manager 检查字体匹配结果
不要只靠“图出来了”就认为成功——得确认 Matplotlib 真的选中了中文字体。执行以下代码:
import matplotlib.font_manager as fm<br>props = fm.FontProperties(family='sans-serif', size=12)<br>print(fm.findfont(props))
输出路径应指向一个含中文字符的字体文件(如 C:\Windows\Fonts\msyh.ttc),而不是 DejaVuSans.ttf。如果仍返回 DejaVu 字体,说明配置未被读取或缓存未清空。
另一个容易被忽略的点:Jupyter Notebook 中修改 matplotlibrc 后,必须重启 kernel;VS Code 的 Python Interactive 窗口同理。缓存不清,改一百遍配置也没用。


















