中文显示方块是因matplotlib默认字体不支持中文,需配置中文字体及禁用unicode负号。临时方案为设置plt.rcparams['font.sans-serif']和['axes.unicode_minus'];永久方案为修改matplotlibrc并清理缓存。

为什么中文显示成方块?
不是编码问题,也不是 Python 源文件没设 utf-8,而是 matplotlib 默认用的字体(如 DejaVu Sans)根本不包含中文字符。它一遇到汉字就 fallback 到无字形的占位符,结果就是满屏□。
验证方式很简单:from matplotlib import font_manager; [f.name for f in font_manager.fontManager.ttflist]
查一下输出里有没有 SimHei、Microsoft YaHei、PingFang SC 这类名字——没有,就肯定乱码。
临时方案:代码里加两行就能用
适合快速验证、单个 notebook 调试,不用改环境。但每次新开 kernel 都得重写,且对 seaborn 等下游库不一定自动继承。
-
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'KaiTi']—— Windows 推荐顺序;macOS 用['PingFang SC', 'Heiti SC'];Linux 用['WenQuanYi Micro Hei', 'Noto Sans CJK'] -
plt.rcParams['axes.unicode_minus'] = False—— 否则负号-显示为方块 - 必须放在绘图代码之前,且建议在 notebook 第一个 cell 执行
- 执行后需重启 kernel 才能生效(仅限已运行过的 cell,新 cell 不受影响)
永久方案:改 matplotlibrc 配置文件
一劳永逸,所有 notebook 和脚本都生效,但要小心路径和缓存。
- 先定位配置文件:
import matplotlib; matplotlib.matplotlib_fname(),返回类似/path/to/matplotlib/mpl-data/matplotlibrc - 编辑该文件,找到
font.sans-serif :这一行,去掉注释#,并在冒号后添加中文字体名,例如:font.sans-serif : SimHei, Microsoft YaHei, sans-serif - 同样处理
axes.unicode_minus :,改为axes.unicode_minus : False - 字体文件本身必须存在:
SimHei.ttf得放进fonts/ttf/目录(路径可由matplotlib.get_cachedir()+../fonts/ttf推导) - 删掉缓存:
rm -rf ~/.matplotlib(mac/Linux)或手动删除C:\Users\{user}\.matplotlib(Windows)
常见坑和系统差异
很多人卡在这几步上,不是配置错,是细节没对齐:
-
SimHei在 Windows 上通常预装,但 macOS 和 Linux 默认没有,硬写会失效;macOS 必须用PingFang SC或STHeiti,不能照搬 Windows 写法 - conda 环境下,
matplotlibrc可能在envs/{name}/lib/python*/site-packages/matplotlib/mpl-data/,而不是全局路径 - Jupyter Lab 和 classic notebook 对内联渲染略有差异,加一句
%config InlineBackend.figure_format = 'retina'可提升清晰度,但不解决乱码 - 如果用了
seaborn,它默认继承matplotlib设置,但若显式调用seaborn.set_theme(),可能覆盖字体配置,需额外加seaborn.set(font='SimHei')
最麻烦的其实是字体文件路径权限和缓存残留——删了 .matplotlib 目录后,第一次绘图会重建缓存并扫描字体,这过程可能卡几秒,别误以为失败。











