📅 系列:一起学Python | 难度:⭐⭐
🔗 上期回顾:第116天:imread 图像读取
如果你用 Matplotlib 画过图,一定见过这个令人窒息的画面:
标题变成 "RUNOOB - □□□□□"
X轴标签变成 "X□"
Y轴标签变成 "Y□"

这不是你的代码错了,而是 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 负号,解决 - 变方块
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()

# 字体加载同上(省略)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。# 字体加载同上(省略)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()

# 字体加载同上(省略)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)
基础题:绘制一张折线图,标题为"一周气温变化",X轴为"星期",Y轴为"温度(℃)"
进阶题:绘制一张带图例的图表,图例内容为"实际值"和"预测值",确保中文正常显示
挑战题:绘制一张 2×2 多子图看板,所有标题、标签、图例均使用中文
今天我们彻底解决了 Matplotlib 的中文显示问题:
✅ 问题根源:默认字体不含中文字符集
✅ 核心方案:FontProperties(fname=...) 加载本地字体文件,跨平台稳定
✅ 负号修复:axes.unicode_minus = False
✅ 全场景覆盖:标题、轴标签、图例、饼图、颜色条、总标题
✅ 查看字体:font_manager.fontManager.ttflist 获取系统字体列表
关键记忆:fontproperties=prop 管大部分,prop=prop 管图例,textprops 管饼图。
