当前位置:首页>python>一起学Python第117天:Matplotlib 中文显示终极指南——彻底告别"口口口口"乱码噩梦

一起学Python第117天:Matplotlib 中文显示终极指南——彻底告别"口口口口"乱码噩梦

  • 2026-10-11 06:26:33
一起学Python第117天:Matplotlib 中文显示终极指南——彻底告别"口口口口"乱码噩梦

📅 系列:一起学Python | 难度:⭐⭐

🔗 上期回顾:第116天:imread 图像读取

一、每个中国程序员的"必经之路"

如果你用 Matplotlib 画过图,一定见过这个令人窒息的画面:

  • 标题变成 "RUNOOB - □□□□□"

  • X轴标签变成 "X□"

  • Y轴标签变成 "Y□"

这不是你的代码错了,而是 Matplotlib 默认不支持中文字体。它就像一位只懂英文的画家,你让它写中文,它只能给你画方块。

今天这期,我们来彻底解决这个历史遗留问题,而且是一劳永逸的那种。

二、问题根源:为什么 Matplotlib "不认识"中文?

Matplotlib 默认使用DejaVu Sans字体,这套字体没有中文字符集。当遇到中文时,系统找不到对应的字形,只能用 "缺失字符方块" 代替。

同时还有一个"孪生问题":负号 - 也可能显示为方块,因为默认字体对数学符号的支持也不完善。

三、终极解决方案:字体文件加载法(推荐)

我们直接采用最稳定、跨平台、不挑系统的方案:加载本地字体文件。

import matplotlib.pyplot as pltimport matplotlib.font_manager as fmimport numpy as npimport os# ================= 1. 字体加载(解决报错的核心) =================font_path = "simhei.ttf"  # 确保你已经在当前目录上传了 simhei.ttfif not os.path.exists(font_path):    font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"  # 备用系统字体prop = fm.FontProperties(fname=font_path)plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方块的问题

原理说明:

  • fm.FontProperties(fname=...) 直接加载字体文件,不依赖系统是否安装

  • simhei.ttf(黑体)放项目目录下,Windows/macOS/Linux 都能用

  • 如果找不到,自动 fallback 到 Linux 系统的文泉驿字体

  • axes.unicode_minus = False 用普通减号替代 Unicode 负号,解决 - 变方块

四、实战:中文显示的"全场景通关"

示例 1:基础中文图表(入门)

import matplotlib.pyplot as pltimport matplotlib.font_manager as fmimport numpy as npimport os# ================= 1. 字体加载(解决报错的核心) =================font_path = "simhei.ttf"if not os.path.exists(font_path):    font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"prop = fm.FontProperties(fname=font_path)plt.rcParams['axes.unicode_minus'] = False# 数据x = np.array([1, 2, 3, 4, 5])y = np.array([2, 4, 6, 8, 10])plt.figure(figsize=(8, 6))plt.plot(x, y, marker='o', linewidth=2)# 每个中文文本都传入 fontproperties=propplt.title('折线图示例', fontproperties=prop, fontsize=16)plt.xlabel('X轴', fontproperties=prop, fontsize=12)plt.ylabel('Y轴', fontproperties=prop, fontsize=12)plt.grid(True, alpha=0.3)plt.show()
效果:标题、轴标签完美显示中文,负号正常。

示例 2:图例与颜色条的中文处理

# 字体加载同上(省略)x = np.linspace(0, 10, 50)y1 = np.sin(x)y2 = np.cos(x)plt.figure(figsize=(10, 6))plt.plot(x, y1, label='正弦曲线', linewidth=2)plt.plot(x, y2, label='余弦曲线', linewidth=2)plt.title('三角函数对比', fontproperties=prop, fontsize=16)plt.xlabel('弧度', fontproperties=prop)plt.ylabel('函数值', fontproperties=prop)# 图例中文:传入 prop 参数plt.legend(prop=prop, loc='upper right')plt.grid(True, alpha=0.3)plt.show()
💡 关键点:plt.legend() 里的 prop 参数控制图例字体,不是 fontproperties。

示例 3:散点图颜色条 + 中文标注

# 字体加载同上(省略)np.random.seed(42)x = np.random.rand(50)y = np.random.rand(50)colors = np.random.rand(50)plt.figure(figsize=(8, 6))scatter = plt.scatter(x, y, c=colors, cmap='viridis', s=100)plt.title('散点图颜色映射', fontproperties=prop, fontsize=16)plt.xlabel('X 维度', fontproperties=prop)plt.ylabel('Y 维度', fontproperties=prop)# 颜色条中文标签cbar = plt.colorbar(scatter)cbar.set_label('颜色强度', fontproperties=prop)plt.show()

示例 4:多子图全中文看板

# 字体加载同上(省略)fig, axes = plt.subplots(2, 2, figsize=(12, 10))# 子图1axes[0, 0].plot([1, 2, 3], [1, 4, 9])axes[0, 0].set_title('销售额趋势', fontproperties=prop)# 子图2axes[0, 1].bar(['Q1', 'Q2', 'Q3'], [120, 150, 180])axes[0, 1].set_title('季度对比', fontproperties=prop)# 子图3axes[1, 0].pie([30, 70], labels=['A类', 'B类'],                textprops={'fontproperties': prop})axes[1, 0].set_title('占比分析', fontproperties=prop)# 子图4axes[1, 1].hist(np.random.randn(1000), bins=20)axes[1, 1].set_title('分布直方图', fontproperties=prop)# 总标题fig.suptitle('2026年经营分析看板', fontproperties=prop, fontsize=18)plt.tight_layout(rect=[0, 0, 1, 0.96])plt.show()

五、进阶:如何查看系统可用字体?

如果你想知道系统里有哪些字体可以用,运行以下代码:

from matplotlib import font_managerimport matplotlib# 获取所有已注册字体,按名称排序fonts = sorted([f.name for f in font_manager.fontManager.ttflist])for font in fonts:    print(font)
常见中文字体名称速查:
💡 备用方案:如果你不想带字体文件,可以直接用 rcParams 设置系统字体(但换电脑可能失效):
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'PingFang SC']plt.rcParams['axes.unicode_minus'] = False

六、避坑指南

七、参数速查卡

# 字体加载(文章标准写法)import matplotlib.font_manager as fmfont_path = "simhei.ttf"if not os.path.exists(font_path):    font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"prop = fm.FontProperties(fname=font_path)plt.rcParams['axes.unicode_minus'] = False# 标题 / 轴标签plt.title('中文', fontproperties=prop)plt.xlabel('中文', fontproperties=prop)# 图例plt.legend(prop=prop)# 饼图标签plt.pie(..., textprops={'fontproperties': prop})# 颜色条cbar = plt.colorbar()cbar.set_label('中文', fontproperties=prop)# 子图标题ax.set_title('中文', fontproperties=prop)fig.suptitle('中文', fontproperties=prop)

八、今日练习

  1. 基础题:绘制一张折线图,标题为"一周气温变化",X轴为"星期",Y轴为"温度(℃)"

  2. 进阶题:绘制一张带图例的图表,图例内容为"实际值"和"预测值",确保中文正常显示

  3. 挑战题:绘制一张 2×2 多子图看板,所有标题、标签、图例均使用中文

九、总结

今天我们彻底解决了 Matplotlib 的中文显示问题:

  • ✅ 问题根源:默认字体不含中文字符集

  • ✅ 核心方案:FontProperties(fname=...) 加载本地字体文件,跨平台稳定

  • ✅ 负号修复:axes.unicode_minus = False

  • ✅ 全场景覆盖:标题、轴标签、图例、饼图、颜色条、总标题

  • ✅ 查看字体:font_manager.fontManager.ttflist 获取系统字体列表

关键记忆:fontproperties=prop 管大部分,prop=prop 管图例,textprops 管饼图。

🎯 今日金句:代码是理性的,但图表需要讲故事——而故事,最好用母语来讲。解决中文显示,不是技术问题,是对用户的尊重。

最新文章

随机文章