news 2026/9/28 8:19:26

matplotlib中文乱码根治指南:字体配置、排查与跨平台方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
matplotlib中文乱码根治指南:字体配置、排查与跨平台方案

用 matplotlib 画图,最让人血压飙升的瞬间莫过于——图是画出来了,线啊点啊都对,可所有中文标签全变成一个个方框,或者干脆消失。更气人的是,在 PyCharm 里跑没问题,换个 VSCode 终端就乱码,自己电脑好好的一拿到服务器就废。我前前后后踩过不下二十次这种坑,今天把根治方案、排查思路和避坑经验一次说透。无论是刚接触数据可视化的新手,还是被中文折磨已久的写论文人、做报表的职场人,这篇文章都能帮你彻底告别 matplotlib 中文乱码。

1. 中文乱码的本质:不是 matplotlib 的问题,而是字体与编码的错配

1.1 乱码到底是怎么发生的

很多人一遇到乱码就想去重装 matplotlib,其实这跟 matplotlib 本身没什么关系。Matplotlib 默认使用的字体是 DejaVu Sans,这是一套西文字体,里面压根就没有中文字形。当绘图文本里出现“销售数据”“柱状图”这类汉字时,matplotlib 在字体库中找不到对应的字形,于是只能用一个空心方框来代替。Windows 下还会出现一种情况,就是字符被错误解析成乱码符号,比如一堆“□□□□”或者“锟斤拷”,后者其实是编码转换错误导致的经典乱码。

明白了这个原理,解决路径就清晰了:让 matplotlib 使用一款支持中文的字体。常见的可选方案有三种,一是全局修改 rcParams 字体配置,二是安装额外的中文字体到系统,三是动态指定字体文件路径。大部分人推荐第一种,确实也是最稳定的一种。但具体怎么配置、配完为什么还不生效,这里面的门道很多,我下面会逐一拆解。

1.2 字体查找机制:matplotlib 怎么决定用哪个字体

在进入实操前,有必要先了解一下 matplotlib 的字体查找流程,不然遇到findfont: Font family 'SimHei' not found这种报错时还是会一脸懵。

当调用plt.xlabel('年份')时,matplotlib 会进入字体管理器,它先读取当前 rcParams 中font.family和font.sans-serif的配置,然后在系统字体缓存里匹配对应的 TTF/TTC 文件。如果找不到,就会把警告打到终端,并回退到默认字体。注意,这里的“找到”指的是字体文件能被 matplotlib 的字体管理器正常加载,而不是只要系统里装了微软雅黑就万事大吉。某些第三方发行版(比如通过 conda 安装的 matplotlib)可能没有继承系统字体路径,导致明明装了中文字体却仍然乱码。

1.3 对比表格:常见中文字体的适配性

为了让你一目了然地选择,我整理了一个常用中文字体在 matplotlib 中的适配情况表,环境是 Windows 10 + Python 3.10 + matplotlib 3.7。

字体名称系统自带情况matplotlib 中常见写法小字号清晰度是否容易缺字
SimHei(黑体)Windows 自带SimHei较好偶尔
SimSun(宋体)Windows 自带SimSun好少见
Microsoft YaHei(微软雅黑)Windows 自带Microsoft YaHei非常好极少数生僻字
KaiTi(楷体)Windows 自带KaiTi好少见
Noto Sans CJK SC需下载Noto Sans CJK SC非常好无
WenQuanYi Zen HeiLinux 常见WenQuanYi Zen Hei好无
Source Han Sans CN(思源黑体)需下载Source Han Sans CN非常好无

从经验来看,日常出图优先SimHei或Microsoft YaHei,如果要提交期刊或打印,推荐思源黑体,因为它的字形更规范和统一。这里要特别提醒:字体名称必须严格按照 matplotlib 识别的名字来写,不是你在 Word 里看到的名字。比如系统里安装的是“方正小标宋简体”,matplotlib 可能识别不了这种带修饰词的名字,这时就需要用font_manager.fontManager.ttflist查看实际名字。

2. 三种常用解决方案:从永久生效到临时指定

2.1 方案一:全局修改 rcParams(最常用、最实用)

这是最正宗的写法,只要在绘图脚本的最前面加上几行代码,所有文本都会使用中文字体。我一般是这样写的:

import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认无衬线字体为黑体 plt.rcParams['axes.unicode_minus'] = False # 解决负号‘-’显示为方块的问题

第一行很好理解,就是告诉 matplotlib 用黑体渲染文字。第二行axes.unicode_minus设置成False,是为了让坐标轴的负号使用 ASCII 短横线,而不是 Unicode 的减号。为什么必须设置?因为在某些中文字体下,Unicode 减号字形是缺失的,会显示成小方块。这个问题很容易被忽略,导致坐标轴出现“-0.5 变成 □0.5”的怪现象。

完整的使用示例:

import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False days = ['周一', '周二', '周三', '周四', '周五'] temps = [23, 25, 27, 26, 24] plt.plot(days, temps, marker='o') plt.title('一周温度变化') plt.xlabel('星期') plt.ylabel('温度(℃)') plt.show()

这段代码直接跑起来,标题、坐标轴标签就正常了。有一点要注意,font.sans-serif这个键对应的值是一个列表,你可以同时列出多个备选字体,比如['Microsoft YaHei', 'SimHei', 'Arial'],matplotlib 会从左到右依次尝试,直到找到可用的为止。这样即使某个字体在某些系统上不存在,也会自动降级。

2.2 方案二:使用字体管理器动态注册字体(适合无中文环境)

当你把脚本扔到服务器上跑,而服务器是纯 CentOS 系统,往往没有安装任何中文字体,此时方案一就会失效。我们可以在脚本中动态下载并注册一个字体文件,无需系统级安装。第一步,准备一个 TTF 文件,比如从我常用的路径拷贝:

import matplotlib import matplotlib.font_manager as fm # 字体文件路径,TTF或OTF均可 font_path = '/path/to/your/NotoSansCJKsc-Regular.otf' prop = fm.FontProperties(fname=font_path)

然后在使用时,把FontProperties对象传给每个需要中文的绘图接口:

import matplotlib.pyplot as plt # 使用上面的 prop plt.plot(['中文', '数据'], [1, 2]) plt.title('自定义字体', fontproperties=prop) plt.xlabel('类别', fontproperties=prop) plt.ylabel('数值', fontproperties=prop)

这种方式的优势是,即使电脑上没有任何系统中文,只要脚本里带一个字体文件,就能在任何机器上稳定复现。缺点是每次设置文本都要加fontproperties参数,代码冗余。如果你想全局生效,可以这样注册:

import matplotlib.font_manager as fm import matplotlib.pyplot as plt fm.fontManager.addfont('/path/to/your/NotoSansCJKsc-Regular.otf') plt.rcParams['font.family'] = 'Noto Sans CJK SC'

addfont方法在 matplotlib 3.2 之后存在,低于这个版本的也可以手动构建FontProperties再添加到fontManager.ttflist,不过更建议升级到新版。

2.3 方案三:临时修改字体设置(单图快速调试)

有时候只是临时画个示意图,不愿意动全局配置,可以在单个 Figure 对象上临时设置:

import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties # 读取系统字体 font_path = 'C:/Windows/Fonts/msyh.ttc' # Windows 微软雅黑 my_font = FontProperties(fname=font_path, size=12) fig, ax = plt.subplots() ax.set_title('临时图', fontproperties=my_font) ax.set_xlabel('X 轴', fontproperties=my_font)

这一种最灵活,但如果你要写一个有几十个图标的论文,每一个轴都要去指定一遍,绝对会怀疑人生。所以我个人的经验是:写脚本时用方案一的全局配置打底,遇到特殊字体需求再叠加方案二的动态注册。方案三只在快速试错时用。

2.4 三种方案的适用场景对比

方案优点缺点适用环境
全局 rcParams简洁、一行搞定依赖系统已安装字体个人电脑、本地脚本
动态注册 TTF跨平台、可移植需要携带字体文件服务器、云端、共享脚本
单图 FontProperties精准控制代码冗长,易遗漏快速调试、单个特殊图

3. 实操全流程:从检测到修复,一步不落

3.1 先检查当前环境到底缺什么

不要一乱码就照着网上的代码粘贴,第一步应该是定位。打开 Python 终端,执行以下代码查看系统字体列表:

from matplotlib import font_manager fonts = [f.name for f in font_manager.fontManager.ttflist] print(sorted(set(fonts)))

如果输出结果里没有SimHei、Microsoft YaHei这类中文字体,说明当前 Python 环境根本没有扫描到中文,那就需要检查系统是否安装中文字体,或者使用动态注册。如果列表里有中文字体但还是乱码,那问题多半出在代码没有正确指定,比如plt.rcParams['font.sans-serif'] = 'SimHei'这种错误赋值——注意这里应该是一个列表,字符串后面没有加方括号,matplotlib 也会报错。

另外还要查一下 matplotlib 版本,老版本(2.x 及以前)对字体支持不同,建议升级到最新版:

pip install -U matplotlib

升级之后再次运行检测脚本,往往一些莫名其妙的问题就消失了。

3.2 完整修复示例:一个带中文的散点图

假设我们要绘制一个“各季度销售额散点图”,直接上完整代码,这是能直接复现的:

import matplotlib.pyplot as plt # 1. 全局字体设置 plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial'] plt.rcParams['axes.unicode_minus'] = False # 2. 数据 quarters = ['Q1(一季度)', 'Q2(二季度)', 'Q3(三季度)', 'Q4(四季度)'] sales = [125, 180, 210, 165] # 3. 绘图 plt.figure(figsize=(8, 5)) plt.scatter(quarters, sales, s=80, c=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']) plt.title('各季度销售额散点图') plt.xlabel('季度') plt.ylabel('销售额(万元)') plt.grid(True, linestyle='--', alpha=0.5) plt.show()

假如这里运行出来仍然有小方块,大概率是你的Microsoft YaHei字体文件名是msyh.ttc,matplotlib 对 TTC 格式的兼容性略差。解决办法是换用SimHei或者下载单独的 TTF 格式字体。Windows 自带的黑体是simhei.ttf,一般都能被正常识别。

3.3 字体文件放在哪更合适

如果你走的是动态注册路线,字体文件的存放位置也有讲究。不要随便丢在临时目录,否则脚本换台机器就跑不动。建议在项目里建一个fonts/目录,把字体文件统一放在里面,然后通过绝对路径引用。如果你的脚本要给别人用,还可以用os.path.join拼接路径,增强可移植性:

import os import matplotlib.font_manager as fm base_dir = os.path.dirname(os.path.abspath(__file__)) font_path = os.path.join(base_dir, 'fonts', 'SimHei.ttf') fm.fontManager.addfont(font_path)

这样做的好处是,整个项目目录拷贝到任何机器上都能运行。我习惯在团队里统一维护一个fonts文件夹,里面放思源黑体的几个字重文件,这样大家画出来的图风格一致。

3.4 确认修复成功:如何快速判断

修复后,不要只看图是否正常,还要注意看终端有没有警告。如果字体匹配失败,matplotlib 会打印类似findfont: Font family 'SimHei' not found的警告。输出图形正常但终端有警告,说明这次虽然显示了,但下一次可能又找不到。可以写一个自定义字体管理器方法:

import warnings import matplotlib.pyplot as plt with warnings.catch_warnings(): warnings.simplefilter("error") plt.rcParams['font.sans-serif'] = ['SimHei']

这样可以将警告升级为异常,方便在 CI 中检测问题。

4. 中文乱码延伸出来的两个高频场景:负号与子图图例

4.1 负号显示成方框的解决技巧

这个我在前面提了一嘴,但值得单独说。很多人设置完中文字体后,正数正常,一遇到负数坐标就显示为方框。原因是轴的刻度默认使用 Unicode 字符 U+2212 作为负号,而这个字符在许多中文字体中不存在。解决办法就是全局设置:

plt.rcParams['axes.unicode_minus'] = False

设置为 False 之后,matplotlib 会改用 ASCII 连字符(-),这样就不会受中文字体限制。如果你不想改全局,也可以在坐标格式器上设置:

import matplotlib.ticker as ticker ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%g'))

这会把负号也转成普通 ASCII 字符,道理相同。不过我始终推荐改 rcParams,简单且不易遗漏。

4.2 图例和子图中的中文怎么处理

图例乱码和标题乱码原理完全一致,但处理时有一个小坑:如果你使用了label参数,并且全局字体设置生效,图例就会正常;但如果你手动创建了单独的图例对象,可能还要重新指定字体:

plt.legend(prop={'family': 'SimHei'})

对于子图,很多人会在plt.subplots()后忘记设置字体,导致每个子图的标题和刻度乱码。最保险的做法是使用plt.rcParams全局设置后,子图不需要额外操作。但要注意,如果你在一个脚本中混用了不同字体,子图之间可能会互相干扰,最好用一个命名规范。比如:

fig, axes = plt.subplots(2, 2, figsize=(10, 8)) axes[0, 0].plot(...) axes[0, 1].plot(...)

这里只要开头设置了 font.sans-serif,所有子图的标题、坐标轴都会正常,不需要每个轴都设置。

4.3 跨平台脚本的字体兼容方案

如果你要在 Windows、macOS、Linux 三端运行同一套绘图脚本,直接写死SimHei在 macOS 上就会失效。这就需要做平台判断:

import platform import matplotlib.pyplot as plt system = platform.system() if system == 'Windows': font_list = ['Microsoft YaHei', 'SimHei'] elif system == 'Darwin': font_list = ['PingFang SC', 'Heiti SC', 'Songti SC'] else: font_list = ['Noto Sans CJK SC', 'WenQuanYi Zen Hei'] plt.rcParams['font.sans-serif'] = font_list plt.rcParams['axes.unicode_minus'] = False

这是一个万金油配置,虽然不能保证每个系统都完美,但至少不会出大毛病。在 macOS 上,PingFang SC是系统默认中文字体,matplotlib 一般能识别。Linux 上如果没有Noto Sans CJK SC,需要安装fonts-noto-cjk包,或者用方案二动态加载字体文件。

5. 常见问题与排查技巧实录

5.1 速查表:乱码场景与解决路径

现象原因解决方案
中文显示为空心方框默认字体不含中文字形设置font.sans-serif为中文字体
负号显示为方框Unicode 减号缺失设axes.unicode_minus=False
终端有 findfont 警告指定字体不存在检查字体名称或动态 addfont
在 PyCharm 正常,终端乱码环境变量不同或字体缓存未刷新重启 kernel,清空 matplotlib 缓存~/.matplotlib
设置后仍然乱码配置文件 rcParams 被后置代码覆盖搜索代码中是否还有plt.rcParams赋值
Font family not found报错字体名拼写错误用fontManager.ttflist核对准确名称
复制到服务器上乱了服务器系统无中文字体动态加载 TTF 或安装字体

5.2 细节坑:配置被覆盖和缓存遗忘

比较隐蔽的一个情况是,你在 A 文件开头设置了plt.rcParams['font.sans-serif']=['SimHei'],但后来在 B 文件或同一个脚本后面又调用了plt.style.use('seaborn')之类的样式,这个样式会重置 rcParams,导致中文字体设置失效。解决方法是把字体设置放在plt.style.use之后,或者使用plt.rcParams.update({'font.sans-serif': ['SimHei']})强制更新。

还有缓存问题,matplotlib 首次运行时会扫描系统中所有字体,生成一个缓存文件在用户目录的.matplotlib文件夹下。当新装了中文字体后,matplotlib 仍然使用旧缓存,导致识别不到。解决方法:

rm -rf ~/.matplotlib

或者直接用 Python 删:

import matplotlib import shutil cache_dir = matplotlib.get_cachedir() shutil.rmtree(cache_dir)

清掉之后,下次运行会自动重建缓存,新字体就被识别了。这个操作非常简单,但能解决一大批“明明安装了字体却不生效”的案例。

5.3 进阶:将中文字体嵌入 PDF/SVG 文件

如果你不是只在屏幕上看看,而是要把图片保存后发给别人,还要注意保存图片时是否嵌入了字体。SVG 格式默认会把字体路径记录下来,别人打开时如果系统没有对应字体,可能在他们的电脑上显示乱码。解决办法是在保存时指定字体嵌入方式:

plt.savefig('output.svg', format='svg', bbox_inches='tight')

对于 SVG,matplotlib 生成的路径会通过字体对象来引用文本,通常编辑器能自动处理。更稳妥的是输出高分辨率的 PNG,并使用dpi参数:

plt.savefig('output.png', dpi=300, bbox_inches='tight')

300 DPI 足够印刷,而且渲染时就固定了字形,不会受到查看端字体影响。这是我的惯用做法,出论文图基本不会出错。

5.4 谈起乱码时的额外提醒:CSV 数据源中文乱码

有时候图中的中文标签本身是从文件读入的,比如读取csv文件的中文列名,如果 pandas 读进来就已经是乱码,那 matplotlib 表现出的乱码其实是数据源头的问题。排查时要先打印输出字符串看看是否正确。常见的文件编码问题要用对参数:

import pandas as pd df = pd.read_csv('data.csv', encoding='utf-8')

如果文件是 GBK 编码:

df = pd.read_csv('data.csv', encoding='GBK')

这一层不解决,就算 matplotlib 字体设得再好,图上也只会显示你读进来的乱码字符。所以遇到中文乱码,先分清是“字体导致的方框”还是“数据源导致的乱码”,两者的处理路径完全不同。

6. 工具选型推荐:中文字体选择与编辑器配置

6.1 系统字体怎么看、怎么选

Windows 下打开C:\Windows\Fonts,能看到simhei.ttf、msyh.ttc、simsun.ttc等文件。建议在项目字体文件夹中保留SimHei.ttf和msyh.ttc的副本,但要注意微软雅黑的 TTC 文件在部分 matplotlib 版本中可能加载失败,如果遇到问题,就换用黑体。Linux 下可用fc-list :lang=zh查看已安装中文字体:

fc-list :lang=zh

如果输出为空,先安装:

sudo apt install fonts-noto-cjk

macOS 可以在“字体册”里查看,一般系统自带PingFang.ttc,但 matplotlib 可能只识别为PingFang SC,需要单独测试。我的测试结论是 Matplotlib 3.6 之后对 macOS 的 PingFang 支持已经比较友好,但仍有偶发警告。

6.2 推荐使用的开源免费字体

如果你的需求是公开出版或者商业用途,务必谨慎。微软雅黑等字体有商业授权限制,更适合用开源字体。我最常用的开源字体有两个:思源黑体(Source Han Sans SC)和文泉驿正黑(WenQuanYi Zen Hei)。思源黑体的字形现代、清晰度高,包含简体/繁体/日文/韩文等多字重,最推荐。从 GitHub 下载后解压,把 TTF 或 OTF 文件放在fonts/目录,再用fm.fontManager.addfont()注册即可。

字体下载后要检查大小,正规思源黑体单个 OTF 文件大约 15 MB 左右,如果某个网站给你的文件只有几百 KB,那多半是裁剪版或者非官方版本,加载可能出问题。建议直接从官方 GitHub 仓库 release 页面下载。

6.3 IDE 与终端的中文输出配合

虽然本文主题是 matplotlib,但很多人在 IDE 的终端里输出中文也是乱码,这会影响调试。如果是在 Windows 的 VSCode 终端中运行 Python 脚本,输出中文全是乱码,可能不是 matplotlib 的问题,而是 Python 控制台编码问题。推荐在脚本开头加:

import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

或者更稳妥地,将项目文件统一保存为 UTF-8 编码,并在系统区域设置中勾选“Beta: 使用 Unicode UTF-8 提供全球语言支持”。不过后者会影响整个系统,谨慎开启。对于仅调试,建议用环境变量:

set PYTHONIOENCODING=utf-8

这样设置后,控制台输出的中文也能正常显示。注意,这类设置优先级高于脚本内的sys.stdout重写,更适合临时解决问题的场景。

7. 规避乱码的架构思维:把字体配置做成公共模块

7.1 写一个mpl_config.py公共配置模块

经验丰富之后,你不会在每个脚本里重复写字体配置,而是会把它抽成一个公共模块。比如项目中新建mpl_config.py:

# mpl_config.py import platform import matplotlib.pyplot as plt def setup_chinese_font(): system = platform.system() font_candidates = { 'Windows': ['Microsoft YaHei', 'SimHei'], 'Darwin': ['PingFang SC', 'Heiti SC'], 'Linux': ['Noto Sans CJK SC', 'WenQuanYi Zen Hei', 'SimHei'] } plt.rcParams['font.sans-serif'] = font_candidates.get(system, ['SimHei']) plt.rcParams['axes.unicode_minus'] = False

然后在绘图脚本中调用:

from mpl_config import setup_chinese_font setup_chinese_font()

这样新同事接手项目时,不需要去看冗长的配置代码,只需要调用一个函数,就能保证所有图表不出现中文乱码。在团队协作中,这种方式能极大减少“在哪儿配置字体”的沟通成本。

7.2 在绘图函数中使用字体参数复用

如果你的项目中有大量相似图表,可以统一使用自定义绘图函数,把字体配置封装进去:

def create_figure(title, x, y, xlabel, ylabel): setup_chinese_font() fig, ax = plt.subplots() ax.plot(x, y) ax.set_title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) return fig, ax

这样既保证了字体风格统一,也便于后续统一调整样式。真正把“解决乱码”这一步从每次画图前的重复劳动,变成了一次性的系统工程。

8. 结合热搜词补充:雷达图、散点图与图例中的中文细节

8.1 雷达图中的中文标签处理

雷达图常用于展示多维数据,比如团队能力评估、产品维度分析。我在画雷达图时就遇到过中文标签重叠和乱码叠加的问题。乱码部分还是老办法,全局设置字体即可。但要注意雷达图的刻度标签和角度标签都很多,建议把字体调小一点:

plt.rcParams.update({ 'font.size': 10, 'font.sans-serif': ['SimHei'] })

同时用polar=True创建极坐标子图时,需要自己设置角度标签:

ax.set_xticks(np.linspace(0, 2*np.pi, len(labels), endpoint=False)) ax.set_xticklabels(labels)

这里labels就是中文列表,只要字体设对,渲染完全正常。

8.2 散点图透明度与网格中的中文

散点图的中文乱码主要体现在图例或数据标签上。比如标注特定点,可以用annotate:

plt.annotate('异常点', xy=(x, y), fontproperties=prop)

或者用ax.text。如果还想显示上标下标,比如“温度(℃)”里面的 ℃,就需要确保字体包含该符号。微软雅黑和思源黑体都支持。网格线的中文则很少涉及,但在图例中会有一个坑:直接设置label='中文标签'后如果还乱码,可以单独重设图例字体:

leg = ax.legend() for text in leg.get_texts(): text.set_fontname('SimHei')

这种方法适合特殊情况下,图例文字和全局字体不相同时候强制覆盖。

9. 踩坑实录与个人心得

9.1 那次我在服务器上折腾了两小时

有一次我把本地跑得好好的数据脚本迁移到一台干净的 CentOS 服务器,画图时全是方框。当时第一反应是安装中文字体,于是登录 root 执行yum install -y fontconfig,然后手动下载simhei.ttf放到/usr/share/fonts/,fc-cache -fv刷新后,fc-list已经能看到 SimHei 了,但用 Python 运行时仍然报findfont: Font family 'SimHei' not found。最后才发现,CentOS 上的 matplotlib 是通过pip安装在虚拟环境里的,它没有读取系统的字体目录,而是依赖自己的字体缓存路径。我执行了rm -rf /root/.cache/matplotlib后,重新运行,它重新扫描到了系统字体,问题才真正解决。所以清缓存这个操作,比装字体还重要。

9.2 不要盲目复制网上的代码,先跑通最小案例

网上 90% 的教程会给你这段代码:

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

但是在 Mac 上,SimHei 根本不存在,所以复制过来照样乱码。我的建议是,任何新环境先执行一个最小复现脚本:

import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'PingFang SC'] plt.rcParams['axes.unicode_minus'] = False plt.title('中文测试') plt.show()

如果显示正常,再往大项目里移植;如果不正常,根据警告信息查问题,这样定位效率极高。盲目改代码只会让自己越改越乱。

9.3 利用font_manager自定义回退顺序优化体验

我还会直接创建一个回退字典,把不同字体的优先级拆分:

plt.rcParams['font.sans-serif'] = [ 'PingFang SC', 'Microsoft YaHei', 'SimHei', 'Noto Sans CJK SC', 'WenQuanYi Zen Hei' ]

这样在 Mac 上用苹方,Windows 上用微软雅黑,Linux 上用 Noto,在不同系统上都有不错的显示效果。设置完成后,再调用一次检测函数:

from matplotlib import font_manager available = {f.name for f in font_manager.fontManager.ttflist} print([f for f in plt.rcParams['font.sans-serif'] if f in available])

如果打印出来一个或几个可用字体,说明回退机制能正常工作。这一招很实用,尤其适合你写了平台自动切换逻辑的时候。

9.4 最后分享一个小技巧

如果图形上有需要手动标注的中文文本,可以用ax.annotate时单独指定fontproperties,但更省事的是在rcParams中设置默认字号和字体,然后依赖默认值。我在团队里常常把字体配置和绘图风格一起封装,例如:

import matplotlib.pyplot as plt plt.rcParams.update({ 'font.family': 'sans-serif', 'font.sans-serif': ['Noto Sans CJK SC', 'Microsoft YaHei'], 'axes.unicode_minus': False, 'figure.dpi': 120, 'savefig.dpi': 300, })

这样一来,所有图形默认就是高清、中文正常、负号正常。关键是把这些配置写在一个独立的配置文件里,其他脚本直接import,而不是复制粘贴。

10. 扩展:从乱码到图表美观,还有这些细节值得做

中文不再乱码只是第一步,接下来很多刚入门的朋友会遇到字体大小、标签重叠、图例遮挡等问题,这些虽然不是“乱码”,但和字体设置息息相关。既然你已经把rcParams握在手里,不如顺手把图表美观性一起提升。

调整全局字号:

plt.rcParams.update({ 'font.size': 12, 'axes.titlesize': 16, 'axes.labelsize': 13, 'xtick.labelsize': 11, 'ytick.labelsize': 11, 'legend.fontsize': 10, })

这个配置比每次单独设置fontsize高效得多。再配合tight_layout()或bbox_inches='tight',中文标签基本不会因为边界裁剪而消失。

另外,很多人会遇到保存的 PDF 中文字符变窄的问题,这是因为 PDF 引擎只嵌入字体子集,但 matplotlib 通常能正常嵌入。如果担心,可以选择保存为ps或直接通过矢量图工具二次转换。我的实践是,向期刊投稿时使用 600 DPI 的 TIFF,或者 EPS,但 EPS 对中文字体兼容性略差,所以还是以 PDF 优先。

从日常使用场景来说,如果你是学生交作业、工程师做调试,其实只要学会全局rcParams设置就足够应付 95% 的场景。剩下 5% 的奇葩环境,多看终端警告,多清缓存,多动态加载 TTF,也基本能解决。我先讲到这里,后面如果你们在实际操作中遇到更奇怪的乱码情况,欢迎按本文的排查思路一步步走一遍,大概率都能自己解决。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 8:19:06

用PYTHON3做网站别裸奔,3招免费工具防黑客

用PYTHON3做网站别裸奔,3招免费工具防黑客 域名备案卡住?服务器配置一团乱?很多甲方拿着“用PYTHON3做网站”的需求找过来,第一句话就是:“服务器到底怎么买才不亏?”别急,先别管买哪家,先问自己:你的代码里有没有后门? 用PYTHON3做网站…

作者头像 李华
网站建设 2026/9/28 8:18:59

避坑指南:注册网站模板怎么选才不被坑

避坑指南:注册网站模板怎么选才不被坑 找建站公司最怕什么?怕花大几千甚至上万,最后做出来的东西还不如自己花几百块买个模板改改好看。很多老板在决定上线前,都会反复纠结 注册网站模板 到底 怎么选 ,是找外包公司定制,还是自己用现成的系统?这不仅是钱的问题,更是后期维护、SEO优化和安全性的生死线。…

作者头像 李华
网站建设 2026/9/28 8:18:03

从月均8次故障到0:我们如何用Sealos重建稳定K8s集群

K8s集群又双叒叕崩了?你们是不是也在经历这种循环:半夜被告警电话叫醒,一脸懵地打开电脑,SSH连上master节点,看着满屏的报错日志,心跳跟etcd的leader选举一样忽上忽下。先说一下我们团队的背景:…

作者头像 李华
网站建设 2026/9/28 8:17:59

接口自动化实战:pytest+requests搭建稳定回归体系

接口测试自动化,简单说就是拿脚本代替人肉点接口、看返回、比对结果。这套东西看起来入门门槛不高,但真要在团队里落地,把用例写得稳定、能跑、还愿意维护,里面有不少门道。这篇博文我不扯虚的,直接从我实际做过的项目…

作者头像 李华
网站建设 2026/9/28 8:17:42

网站建设市场需求分析对比评测

3个维度看清网站建设市场需求与报价真相 备案流程一头雾水,让多少老板在 建站报价 面前不敢迈步?很多人以为只要给钱就行,结果卡在域名解析、ICP备案上,钱花了,站没起来。这背后其实是 网站建设市场需求分析 没做透,导致选错服务商、选错技术栈,最后返工成本翻倍。 市场需求到底在变什么?…

作者头像 李华
网站建设 2026/9/28 8:17:23

众车网是哪家公司网站?一文搞懂备案避坑指南

众车网是哪家公司网站?一文搞懂备案避坑指南 很多刚入行的朋友或者准备上线新站点的老板,一听到“ICP备案”这四个字,心里就犯嘀咕:流程到底多复杂?会不会被卡住?其实, 备案流程一头雾水 是90%新手遇到的最大拦路虎。今天咱们不整虚的,直接掰开了揉碎了讲,让你 一文搞懂…

作者头像 李华