matplotlib 中文显示方块需四步:定位真实 matplotlibrc 路径并编辑;确认 simhei.ttf 权限、命名正确并重建字体缓存;配置 font.family、font.sans-serif(simhei 必排首)、axes.unicode_minus;pdf 导出问题需 latex 层支持 ctex 宏包。

plt.rcParams['font.sans-serif'] 配置生效但图表仍显示方块,说明字体路径或缓存没到位,不是单纯加几行代码就能解决的。
查清 matplotlib 实际使用的配置文件位置
乱码问题常因改错了配置文件——你改的是全局或用户目录下的 matplotlibrc,而 Jupyter 实际加载的是当前 Python 环境里 matplotlib 包内置的那个。必须定位到真实路径:
- 在 notebook 单元格中运行:
import matplotlib; print(matplotlib.matplotlib_fname()) - 输出类似
/path/to/env/lib/python3.x/site-packages/matplotlib/mpl-data/matplotlibrc,这才是你要编辑的文件 - 注意:Anaconda 用户路径通常含
anaconda3/lib/...;pip 虚拟环境则在venv/lib/...;Docker 或服务器环境可能挂载在/opt/...
确认 SimHei 字体是否真被 matplotlib 识别
即使把 SimHei.ttf 复制进 fonts/ttf/ 目录,matplotlib 也不一定自动扫描它。常见卡点:
- 字体文件权限不足(Linux/macOS 下需
chmod 644 *.ttf) - 文件名大小写错误(Windows 不敏感,Linux/macOS 敏感,
simhei.ttf≠SimHei.ttf) - 没执行字体重建:
from matplotlib.font_manager import _rebuild; _rebuild()(Python 3.12+ 可能报错,换用matplotlib.font_manager._get_font_cache() or matplotlib.font_manager.FontProperties()触发刷新) - 更可靠的方式:运行
[f.name for f in matplotlib.font_manager.fontManager.ttflist]查看实际加载的字体列表,确认SimHei是否在其中
修改 matplotlibrc 的关键三行不能只取消注释
网上流传的“去掉 # 注释”容易漏掉隐含依赖。真正起效的最小配置是:
-
font.family: sans-serif(必须启用,否则font.sans-serif不生效) -
font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, ...(SimHei必须排第一,且逗号后不加空格) -
axes.unicode_minus: False(否则负号变方块,和中文无关但常一起出现) - 不要动
font.serif或font.monospace,除非你明确要用宋体或等宽中文字体
导出 PDF 时中文消失?那是 nbconvert + XeLaTeX 的事
图表里中文正常,但 jupyter nbconvert --to pdf 出来的 PDF 没字,说明问题不在 matplotlib,而在 LaTeX 渲染链:
- 必须安装完整 TeX 发行版(如 TeX Live),仅装
xelatex命令不够,缺中文宏包会失败 - nbconvert 默认模板不声明中文字体,需额外指定:
nbconvert --to pdf --pdf-engine=xelatex --template=myslide.tplx - 最简方案:在 notebook 第一个单元格加
%%latex并写\usepackage{ctex},强制启用中文支持(仅对含 LaTeX 单元格有效) - 真正一劳永逸:用
--no-input导出前先用nbconvert --to latex生成 .tex 文件,手动检查是否含\usepackage{ctex}和\setmainfont{SimHei}
改完配置、删掉 ~/.cache/matplotlib、重启 kernel,再跑一遍绘图代码——如果还乱码,大概率是字体文件本身损坏,或者系统级字体缓存(如 macOS 的 atsutil)没清干净。这种底层问题没法靠 Python 代码绕过。











