Matplotlib 中文显示(实战总结)

Matplotlib 中文显示问题的根源解析

在使用 Matplotlib 绘图时,你是否遇到过这样的尴尬场景:明明数据清晰、图表美观,可标题、坐标轴标签却显示成一串乱码,比如“����”或“□□□□”?这其实是 Matplotlib 中文显示问题的典型表现。这个问题并不复杂,但很多初学者容易忽略其背后的原因。

简单来说,Matplotlib 默认使用的字体不支持中文,它只内置了西文字符的显示能力。当你在图中添加中文内容时,系统无法找到合适的字体来渲染这些字符,于是就出现了“缺失字体”或“乱码”的现象。

这就像你去餐厅点了一道川菜,但服务员只懂英语,你用中文点菜,他听不懂,只能给你一个空白菜单。解决方法不是换餐厅,而是让服务员学会中文。在 Matplotlib 中,我们就要“教”它如何显示中文。

要解决这个问题,核心思路是:为 Matplotlib 指定一个支持中文的字体。接下来我们将一步步带你完成这个过程。

常见中文显示问题的表现形式

在正式操作前,先看看你是否遇到了以下典型问题:

  • 图表标题显示为 ????□□□□
  • 坐标轴标签(如“月份”“销售额”)变成乱码
  • 图例中文内容无法显示,仅显示英文或空格

这些问题的共同点是:图表内容中包含中文,但绘图时未指定中文字体

我们可以通过一个简单的例子来复现这个问题:

import matplotlib.pyplot as plt

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图")  # 中文标题
plt.xlabel("月份")      # 中文横坐标
plt.ylabel("销售额(万元)")  # 中文纵坐标
plt.show()

运行这段代码,你会发现图表标题和坐标轴标签都变成了乱码。这正是 Matplotlib 中文显示问题的直接体现。

解决方案一:使用系统自带的中文字体

最简单、最直接的解决方法是使用系统中已安装的中文字体。不同操作系统的中文字体不同,我们分别说明:

Windows 系统

Windows 常见中文字体包括:SimHei(黑体)、Microsoft YaHei(微软雅黑)、FangSong(仿宋)等。

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图")
plt.xlabel("月份")
plt.ylabel("销售额(万元)")
plt.grid(True)
plt.show()

注释说明:

  • plt.rcParams['font.sans-serif']:设置默认无衬线字体,传入字体名称列表
  • ['SimHei']:指定使用黑体,它是 Windows 常见的中文字体
  • plt.rcParams['axes.unicode_minus'] = False:解决负号显示为方块的问题,非常重要!

macOS 系统

macOS 常见中文字体包括:PingFang SC(苹方)、Heiti SC(黑体-简)、STHeiti(华文黑体)等。

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Heiti SC', 'STHeiti']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图")
plt.xlabel("月份")
plt.ylabel("销售额(万元)")
plt.grid(True)
plt.show()

注释说明:

  • 传入字体列表时,建议按优先级排序,系统会从左到右尝试加载
  • PingFang SC 是 macOS 的默认中文字体,优先使用

Linux 系统

Linux 系统中中文字体路径较复杂,常见字体有:WenQuanYi Micro HeiNoto Sans CJK SC 等。可通过命令行查看:

fc-list :lang=zh | grep -i "hei\|song\|fang"

示例代码:

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图")
plt.xlabel("月份")
plt.ylabel("销售额(万元)")
plt.grid(True)
plt.show()

解决方案二:使用自定义字体文件

如果系统中没有合适的中文字体,或者你想使用特定字体(如“思源黑体”“阿里巴巴普惠体”),可以手动下载字体文件并加载。

步骤 1:下载字体文件

从官方网站下载 .ttf.otf 格式的字体文件,例如:思源黑体

步骤 2:加载字体

import matplotlib.pyplot as plt
from matplotlib import font_manager

font_path = "/path/to/SourceHanSansSC-Regular.otf"  # 修改为你本地的路径

font_prop = font_manager.FontProperties(fname=font_path)

plt.rcParams['font.sans-serif'] = [font_prop.get_name()]
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图", fontproperties=font_prop)
plt.xlabel("月份", fontproperties=font_prop)
plt.ylabel("销售额(万元)", fontproperties=font_prop)
plt.grid(True)
plt.show()

注释说明:

  • font_manager.FontProperties(fname=...):从指定路径加载字体
  • font_prop.get_name():获取字体名称,用于设置 font.sans-serif
  • fontproperties=font_prop:在每个文本元素中单独指定字体,更灵活

常见问题与调试技巧

问题现象 可能原因 解决方法
标题显示为方块 字体未正确加载 检查字体路径是否正确,字体文件是否损坏
负号显示为方块 Unicode 负号未启用 添加 plt.rcParams['axes.unicode_minus'] = False
图表中部分文字显示正常 字体支持不完整 检查字体是否支持所需字符集
字体在不同机器上显示不同 字体文件未随项目部署 将字体文件打包到项目中,使用绝对路径

调试建议

  1. 使用 plt.rcParams['font.sans-serif'] 查看当前字体设置
  2. 通过 font_manager.findfont() 检查字体是否存在
import matplotlib.font_manager as fm

fonts = [f.name for f in fm.fontManager.ttflist if 'hei' in f.name.lower()]
print("包含 'hei' 的字体:", fonts)

实际项目中的最佳实践

在实际开发中,我们建议将字体配置封装成独立模块,避免重复代码:

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

def setup_chinese_font():
    """配置 Matplotlib 中文显示"""
    # 尝试多个中文字体,优先级从高到低
    fonts = [
        'SimHei', 'Microsoft YaHei', 'PingFang SC',
        'WenQuanYi Micro Hei', 'Noto Sans CJK SC'
    ]
    
    # 设置字体
    plt.rcParams['font.sans-serif'] = fonts
    plt.rcParams['axes.unicode_minus'] = False  # 解决负号问题
    
    # 验证字体是否加载成功
    try:
        font = fm.FontProperties(fname=fm.findfont(fm.FontProperties(family=fonts[0])))
        print(f"成功加载字体: {font.get_name()}")
    except Exception as e:
        print("字体加载失败:", e)

setup_chinese_font()

在主程序中调用:

from config_font import setup_chinese_font

setup_chinese_font()

plt.figure(figsize=(8, 5))
plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
plt.title("销售趋势图")
plt.xlabel("月份")
plt.ylabel("销售额(万元)")
plt.show()

总结与建议

Matplotlib 中文显示问题本质上是字体缺失导致的。通过为 Matplotlib 指定支持中文的字体,即可完美解决。

核心要点回顾:

  • 使用 plt.rcParams['font.sans-serif'] 设置字体
  • 添加 plt.rcParams['axes.unicode_minus'] = False 避免负号乱码
  • 优先使用系统自带字体,如 SimHei、PingFang SC
  • 复杂项目建议封装字体配置逻辑
  • 字体路径要确保可访问,避免绝对路径依赖

掌握这些技巧后,你就可以在任何项目中自由使用中文标题、标签和图例,让图表真正“说人话”。无论你是做数据分析、可视化展示,还是撰写技术报告,Matplotlib 中文显示的正确配置,都是专业表达的基础。