Python Matplotlib绘图中文乱码解决:标题与坐标轴显示方框的处理方法

慢慢来
慢慢来
发布时间:2026-11-14 | 4人浏览过
原创

针对Python使用Matplotlib绘图时图表标题、坐标轴标签及图例出现中文方框乱码和负号显示异常的问题,深入分析其字体缺失原因,提供基于rcParams全局配置、FontProperties局部指定以及matplotlibrc配置文件的完整解决方法与系统排查步骤。

在使用 Python 的 Matplotlib 库绘制图表时,如果在标题、坐标轴标签或图例文本中使用中文字符,渲染出来的图像往往会将中文字符显示为一个个中空的矩形方框(通常被称为“豆腐块”),并在终端输出类似 UserWarning: Glyph 28165 missing from font(s) DejaVu Sans 的警告。要彻底解决该问题,核心在于为 Matplotlib 指定本地操作系统已安装的合规中文字体,并同步关闭负号的 Unicode 转换以防减号乱码。

一、问题根源分析:为什么会出现中文字符方框与负号异常

Matplotlib 的默认排版与渲染引擎在初始化时,使用内置的英文字体配置(默认通常为 DejaVu Sans)。该字体仅包含 ASCII 字符及部分西欧语言符号,并未打包中日韩(CJK)统一表意文字的字形轮廓(Glyphs)。

当绘图指令传入中文字符串时,字体管理模块无法在默认字库中查找到对应 Unicode 编码的字形轮廓,系统只能降级渲染为占位符方框。此外,Matplotlib 默认启用了将 ASCII 连字符负号映射为专业排版 Unicode 减号(U+2212)的机制,如果所选用的中文字体未覆盖该特定符号,就会导致坐标轴负数刻度也变成方框。

Python Matplotlib绘图中文乱码解决:标题与坐标轴显示方框的处理方法
图 1:Matplotlib 字体检索路径与方框故障产生原理

二、排查与准备:查询当前操作系统中可用中文字体

在配置 Matplotlib 之前,首要任务是确认当前计算环境中安装了哪些可用的中文字体。不同操作系统自带的字体族名称(Font Family Name)并不一致,如果配置了一个系统中不存在的字体名,Matplotlib 仍会回退到默认英文字体,无法解决方框问题。

操作系统平台 推荐字体名称(英文标识) 对应中文字体名称 适用场景
Windows Microsoft YaHei, SimHei, SimSun 微软雅黑、黑体、宋体 Windows 桌面或本地开发环境
macOS PingFang SC, Arial Unicode MS, Heiti SC 苹方-简、Arial Unicode、黑体-简 Mac 笔记本及工作站
Linux / 容器 Noto Sans CJK SC, WenQuanYi Micro Hei 思源黑体、文泉驿微米黑 Ubuntu、CentOS 服务器或 Docker 部署环境

若不确定操作系统内确切的字体家族名称,可以运行以下代码片段进行快速列举与筛选:

from matplotlib import font_manager

# 获取系统字体管理器中的所有字体名称
all_fonts = set(f.name for f in font_manager.fontManager.ttflist)

# 筛选包含常见中文拼音及关键词的可用字体
keywords = ['hei', 'song', 'kai', 'fang', 'yahei', 'cjk', 'chinese', 'pingfang']
available_chinese_fonts = [name for name in all_fonts if any(k in name.lower() for k in keywords)]

print("系统已安装的可用中文字体:")
for font in sorted(available_chinese_fonts):
    print(" -", font)

三、核心方案:通过 plt.rcParams 进行全局配置(推荐方法)

这是数据分析与日常绘图中最快捷、最常用的方法。通过在代码导入 Matplotlib 后修改全局运行时配置参数(plt.rcParams),可以在不需要更改系统文件的前提下,对当前运行环境中的所有后续绘图即时生效。

Python Matplotlib绘图中文乱码解决:标题与坐标轴显示方框的处理方法
图 2:Matplotlib 中文与负号配置标准化实施步骤

标准实现代码示例

在编写绘图代码时,建议将 Windows、macOS 和 Linux 的常用中文字体按优先级组合成列表赋给 font.sans-serif。这样无论代码在团队成员的哪种设备上运行,都能依次找到可用的中文字体:

import matplotlib.pyplot as plt
import numpy as np

# 1. 配置无衬线字体回退链,优先匹配系统中存在的中文字体
plt.rcParams['font.sans-serif'] = [
    'Microsoft YaHei',      # Windows 常用
    'PingFang SC',          # macOS 常用
    'Noto Sans CJK SC',     # Linux / 容器 常用
    'SimHei',               # 传统黑体兜底
    'sans-serif'
]

# 2. 修复负号方框乱码:使用标准 ASCII 连字符显示负号
plt.rcParams['axes.unicode_minus'] = False

# 3. 构造测试数据(包含正负数以检验负号)
x = np.linspace(-5, 5, 100)
y = np.sin(x) * 10

# 4. 创建图表并检验中文渲染
plt.figure(figsize=(8, 4.5), dpi=100)
plt.plot(x, y, color="#345E82", linewidth=2, label="正弦采样曲线")

plt.title("正弦波动实验数据统计(含负值区间)", fontsize=14, pad=12)
plt.xlabel("测试周期偏移量 (单位: 秒)", fontsize=11)
plt.ylabel("信号增益幅度 (单位: dB)", fontsize=11)
plt.grid(True, linestyle="--", alpha=0.5)
plt.legend(loc="upper right")

plt.tight_layout()
plt.show()
重点提示:Seaborn 等衍生库重置样式的避坑要点

如果绘图代码中调用了 seaborn.set_theme() 或 sns.set_style(),Seaborn 会将其自带的英文字体配置重新写回 Matplotlib 的 rcParams,导致刚刚设置的中文字体被冲掉。因此,请务必在调用任何样式初始化函数之后再执行字体配置,或者将字体参数直接传递给主题配置字典。

四、替代方案:使用 FontProperties 局部指定特定字体

如果是在公共项目、SDK 库开发或无法随意变更全局 rcParams 的工程中,可以通过 FontProperties 显式指定单处文本的字体属性。这种方式还可以直接加载本地独立的 .ttf 或 .otf 字体文件,彻底解决生产服务器无需安装系统字体即可绘图的需求。

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 方式 A:直接通过系统字体名称初始化
font_title = FontProperties(family='Microsoft YaHei', size=14, weight='bold')
font_axis = FontProperties(family='Microsoft YaHei', size=11)

# 方式 B:直接指定外部字体文件路径(跨平台服务器免安装神器)
# font_custom = FontProperties(fname='/data/fonts/SourceHanSansSC-Regular.otf', size=12)

plt.figure(figsize=(7, 4))
plt.plot([1, 2, 3], [10, 20, 15], marker='o', color='#AD8060')

# 在需要显示中文的组件中显式传入 fontproperties
plt.title("季度生产合格率汇总", fontproperties=font_title)
plt.xlabel("测试批次", fontproperties=font_axis)
plt.ylabel("合格数量 (个)", fontproperties=font_axis)

plt.tight_layout()
plt.show()

五、永久生效方案:修改 matplotlibrc 配置文件

如果希望在个人工作站上每次启动 Python 或 Jupyter Notebook 时都自动具备中文字体支持,而无需在每个脚本开头重复编写配置代码,可以通过修改本地的 matplotlibrc 配置文件实现永久生效。

  1. 定位配置文件路径:在 Python 终端中执行以下命令查看当前生效的配置路径:
    import matplotlib
    print(matplotlib.matplotlib_fname())
    # 输出示例: /Users/username/.matplotlib/matplotlibrc 或 Python环境包目录下
  2. 修改配置文件参数:使用文本编辑器打开该文件,检索并修改以下两行(去掉开头的 # 注释):
    font.family: sans-serif
    font.sans-serif: Microsoft YaHei, PingFang SC, SimHei, DejaVu Sans
    axes.unicode_minus: False
  3. 清理字体缓存(至关重要):Matplotlib 会在本地缓存系统字体索引(fontlist-*.json)。修改配置或向系统新增中文字体后,如果缓存未更新,仍会出现方框。需找到并删除缓存目录:
    import matplotlib
    print(matplotlib.get_cachedir())
    # 将打印出的缓存目录(如 ~/.cache/matplotlib)中的 json 缓存文件删除后重启环境
Python Matplotlib绘图中文乱码解决:标题与坐标轴显示方框的处理方法
图 3:三种解决方式的多维度对比与选型考量

六、排错总结与常见异常自检导图

在实际配置过程中,若按照步骤设置后仍存在异常,可以通过以下决策导图进行快速自检定位:

Python Matplotlib绘图中文乱码解决:标题与坐标轴显示方框的处理方法
图 4:字体排障与方框消除快速自检导图

七、总结

Matplotlib 中文标题与坐标轴方框乱码的实质是默认字体缺失 CJK 字形轮廓,而负号异常则是由于 Unicode 编码减号(U+2212)映射缺失。掌握以下核心要点即可平稳处理各类环境中的中文绘图需求:

  • 最轻量解法:在绘图代码前配置 plt.rcParams['font.sans-serif'] 包含目标系统的中文字体名,并同步设置 plt.rcParams['axes.unicode_minus'] = False。
  • 多环境通用:跨平台开发时在 font.sans-serif 中传入多种主流字体的列表,形成自动向下回退链。
  • 独立无依赖:在无 root 权限或轻量 Linux 容器中,可通过 FontProperties(fname="...") 挂载单独的字体文件。
  • 缓存刷新:遇到任何配置已修改但图形依旧不生效的现象,先删除 matplotlib.get_cachedir() 目录下的字体缓存并重启运行时环境。
相关专题:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表