根本原因是matplotlib默认不加载系统中文字体且字体缓存未识别可用中文字体;需手动设置font.sans-serif、禁用mathtext.fontset、设axes.unicode_minus=False,并强制刷新字体缓存或显式添加字体文件。

matplotlib绘图中文显示为方块或问号
根本原因是 matplotlib 默认不加载系统中文字体,且其内部字体缓存未识别可用的中文字体路径。即使系统有 SimHei、Noto Sans CJK 或 Source Han Sans 等字体,plt.show() 仍可能渲染成方块(□)或空格。
手动指定 font.sans-serif 并禁用 mathtext.fontset
最直接有效的做法是修改 matplotlib 的运行时配置,而非改全局配置文件(容易被覆盖或失效):
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei', 'KaiTi', 'FangSong', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Source Han Sans CN'] plt.rcParams['axes.unicode_minus'] = False # 解决负号'−'显示为方块的问题 plt.rcParams['mathtext.fontset'] = 'stix' # 避免启用 mathtext 导致字体 fallback 失败
- 列表中字体名必须与系统实际安装的字体名称完全一致(大小写敏感),可用
fc-list :lang=zh(Linux/macOS)或 PowerShell 中[System.Drawing.Text.InstalledFontCollection]::new().Families(Windows)查真实名称 - 把常用中文字体按优先级从左到右排列,matplotlib 会逐个尝试,第一个能加载的即生效
-
axes.unicode_minus=False是必须项,否则负号会被当成数学符号走 mathtext 渲染路径,而 mathtext 不支持中文字体
验证字体是否真正加载成功
仅设 font.sans-serif 不代表字体已就绪——matplotlib 会在首次绘图时构建字体缓存,若缓存损坏或路径不可读,仍会回退到无中文支持的字体。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 强制刷新字体缓存:
import matplotlib.font_manager as fm; fm._rebuild()(执行后重启 Python 进程才完全生效) - 检查当前生效字体:
print([f.name for f in fm.fontManager.ttflist if 'simhei' in f.name.lower() or 'sans' in f.name.lower()]) - 打印实际用于渲染的字体:
print(plt.rcParams['font.sans-serif'][0]),再配合plt.title('测试中文')+plt.show()观察是否真显示
在 Docker 或无 GUI 环境中渲染中文图
服务器环境常缺字体文件和 X11 支持,Agg 后端无法访问系统字体目录,直接报 findfont: Font family ['sans-serif'] not found。
- 必须提前复制字体文件(如
simhei.ttf)到项目目录,例如./fonts/SimHei.ttf - 用
fm.fontManager.addfont()注册:fm.fontManager.addfont('./fonts/SimHei.ttf'),再设rcParams['font.sans-serif'] = ['SimHei'] - 确保后端为非交互式:
import matplotlib; matplotlib.use('Agg')必须放在import pyplot之前 - 避免使用
plt.show(),改用plt.savefig('out.png', bbox_inches='tight', dpi=150)
最容易被忽略的是:字体名 ≠ 文件名,也 ≠ 控制面板里看到的“显示名称”;同一个字体在不同系统上注册的 f.name 可能完全不同。不要依赖猜测,一定要用 fm.fontManager.ttflist 实际枚举并匹配。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










