jupyter中文乱码主因是plt.rcparams['font.sans-serif']未正确配置,需同时解决字体存在性、缓存清理和axes.unicode_minus=false三问题;导出pdf乱码则属latex流程,须配tex发行版与ctex宏包。

plt.rcParams['font.sans-serif'] 设置不对,是绝大多数 Jupyter 中文乱码的直接原因。不是装了中文语言包就自动生效,Matplotlib 默认根本不用中文字体,得手动指定,而且必须配对解决两个问题:字体路径可用 + Unicode 负号不崩。
为什么 plt.rcParams['font.sans-serif'] = ['SimHei'] 会失效?
这行代码本身没错,但实际执行时可能卡在三个地方:
-
SimHei在你的系统里根本不存在——Windows 有,macOS/Linux 默认没有,pip install不会自动装字体文件 - 你改了配置,但没清 Matplotlib 缓存,旧字体映射还在内存里,重启 kernel 也不管用
- 只设了
font.sans-serif,漏掉axes.unicode_minus = False,负号(如 -5)显示成方块
怎么确认自己有哪些中文字体可用?
别猜,直接查:
import matplotlib.font_manager as fm fonts = [f.name for f in fm.fontManager.ttflist] print(sorted(set(fonts)))
运行后看输出里有没有 SimHei、Microsoft YaHei、Noto Sans CJK SC 或 AR PL UKai CN 这类常见中文字体名。没有就别硬写 ['SimHei'],换成列表里真实存在的那个。
临时生效 vs 一劳永逸:两种改法区别在哪?
临时改(每次 notebook 开头加):
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['Noto Sans CJK SC'] # 替换为你查到的真实字体名 plt.rcParams['axes.unicode_minus'] = False
一劳永逸(改全局配置):
- 先运行
import matplotlib; print(matplotlib.matplotlib_fname())找到matplotlibrc文件位置 - 编辑该文件,取消注释并修改两行:
font.family: sans-seriffont.sans-serif: Noto Sans CJK SC, DejaVu Sans, Liberation Sans, Bitstream Vera Sans, sans-serif - 删掉缓存:
rm -rf ~/.cache/matplotlib(Linux/macOS)或del /q "%LOCALAPPDATA%\matplotlib\cache"(Windows) - 重启 Jupyter Notebook 进程(不只是 restart kernel)
导出 PDF 时中文又变方块?那是 nbconvert+XeLaTeX 的事
图表里中文正常 ≠ 导出 PDF 正常。这是因为 jupyter nbconvert --to pdf 走的是 LaTeX 流程,和 Matplotlib 字体无关:
- 必须安装完整 TeX 发行版(如 TeX Live 或 MacTeX),不能只装
xelatex命令 - 需要额外传参:
jupyter nbconvert --to pdf --no-input --pdf-default-latex-engine=xelatex - 若仍乱码,说明 LaTeX 模板没加载中文字体,得在 notebook 里加 raw cell,写 LaTeX 命令:
\usepackage{ctex}
最易被忽略的一点:改完 matplotlibrc 后不删缓存,或者改了但没重启 Jupyter server,这两步跳过,前面所有操作都白做。











