背景:为什么 Matplotlib 显示中文会变成”豆腐块”?

如果你用过 Python 的 Matplotlib 或 Seaborn 做数据可视化,可能遇到过这样的问题:图表里的中文文字全部变成了一个个小方块,俗称”豆腐块”(tofu)。

这是为什么呢?

简单来说,Matplotlib 默认使用的字体不包含中文字符。就像你用英文打字机打中文,打出来当然是一堆乱码。解决方法就是告诉 Matplotlib:”请用一个支持中文的字体来显示文字。”

网上有很多解决方案,但哪种最靠谱?能不能跨平台(Windows、macOS、Linux)通用?我决定做个系统性测试。

测试方案

我设计了 6 种常见的解决方案,每种都用 GitHub Actions 在三个平台上自动运行,Python 版本统一使用 3.14。

方案 名称 原理
方法1 rcParams 设置 在代码里直接告诉 Matplotlib 用什么字体
方法2 matplotlibrc 配置文件 写一个配置文件,让 Matplotlib 每次启动都读取
方法3 FontProperties 手动指定字体文件路径
方法4 addfont() 把字体文件加载到 Matplotlib 的字体管理器
方法5 系统字体自动检测 让脚本自动找系统里的中文字体
方法6 下载开源字体 直接下载 Noto Sans CJK 字体使用

测试环境

  • 平台:Windows (windows-latest)、macOS (macos-latest)、Ubuntu (ubuntu-latest)
  • Python:3.14
  • 库版本:Matplotlib + Seaborn(最新版)
  • 自动化:GitHub Actions(18 个 job 并行运行)

测试结果

经过人工验证每个平台生成的 PNG 图片,结果如下:

方案 Windows macOS Ubuntu 结论
方法1 rcParams ✅ 正常 ✅ 正常 ✅ 正常 推荐
方法2 matplotlibrc ❌ 豆腐块 ❌ 豆腐块 ❌ 豆腐块 不推荐
方法3 FontProperties ✅ 正常 ✅ 正常 ✅ 正常 推荐
方法4 addfont ✅ 正常 ✅ 正常 ✅ 正常 推荐
方法5 系统字体 ❌ 失败 ❌ 失败 ❌ 失败 不可用
方法6 Noto Sans ✅ 正常 ✅ 正常 ✅ 正常 推荐

关键发现

  1. matplotlibrc 配置文件方案全平台失败:这是网上很多教程推荐的方法,但实测在所有平台上都显示豆腐块。可能是因为配置文件的字体设置没有被正确加载。

  2. 系统字体自动检测方案不可用:这个方案的脚本在所有平台上都运行失败,可能是脚本本身的问题。

  3. 四种方案跨平台可用:rcParams、FontProperties、addfont()、下载开源字体,这四种方法在所有平台上都能正常显示中文。

  4. 不同方案可能使用不同字体:虽然都能正常显示,但不同方案/平台可能使用了不同的字体(如 SimHei、Noto Sans CJK 等),视觉效果可能略有差异。

推荐方案

方案1:rcParams 设置(最简单)

import matplotlib.pyplot as plt

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Noto Sans CJK SC', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

优点:代码最少,全局生效 缺点:需要系统安装了对应字体

方案4:addfont()(最可靠)

import matplotlib.pyplot as plt
from matplotlib import font_manager

# 加载字体文件
font_path = '/path/to/NotoSansCJKsc-Regular.otf'
font_manager.fontManager.addfont(font_path)

# 设置字体
plt.rcParams['font.sans-serif'] = ['Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False

优点:不依赖系统字体,字体文件可以打包分发 缺点:需要额外下载字体文件

方案6:下载开源字体(最可控)

直接下载 Noto Sans CJK 字体,然后用方案4的方法加载。

优点:字体开源免费,跨平台一致 缺点:需要额外步骤下载字体

总结

场景 推荐方案
快速原型/本地开发 方法1 (rcParams)
需要跨平台一致 方法6 (下载 Noto Sans CJK) + 方法4 (addfont)
项目需要打包分发 方法4 (addfont) + 内嵌字体文件

避坑提醒

  • ❌ 不要用 matplotlibrc 配置文件方案,实测全平台失败
  • ❌ 不要依赖系统字体自动检测,脚本容易出错
  • ✅ 优先使用 rcParams 或 addfont() 方案

测试仓库

完整的测试代码和 GitHub Actions 配置可以在以下仓库找到:

GitHub 仓库ZhulongNT/mpl-chinese-font-test

Actions 运行记录Run #26954523100


本文测试基于 Python 3.14、Matplotlib 和 Seaborn 最新版,测试时间 2026 年 6 月。如果你在使用过程中遇到问题,欢迎在 GitHub 仓库提 issue。