第一次用matplotlib画带中文的图表时,十个人里有九个会遇到方框乱码。这个问题困扰了无数刚入门的数据分析师,我自己当年也被坑得不轻。根本原因在于matplotlib默认使用的字体库不包含中文字符集,而不同操作系统对字体的管理方式又存在差异。
在Windows系统里,微软雅黑、宋体这些中文字体是预装的,但matplotlib并不知道该用哪个。macOS虽然自带苹方、华文黑体等优质字体,但字体名称的英文标识和Windows完全不同。Linux服务器就更麻烦了,很多精简版系统压根没装中文字体。更糟的是,当你在本地开发环境调好了字体,把代码放到Docker容器或无头服务器上运行时,中文又变成了乱码。
Windows用户其实最省心,因为系统自带完整的中文字体库。关键是要告诉matplotlib使用哪个字体。打开Python脚本,在最开始加上这两行:
python复制import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常
如果微软雅黑不可用,可以尝试这些备选方案:
苹果系统的字体管理比较特殊,推荐使用以下任一方案:
python复制plt.rcParams['font.sans-serif'] = ['Songti SC'] # 宋体-简
# 或者
plt.rcParams['font.sans-serif'] = ['PingFang SC'] # 苹方-简
# 或者
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 跨平台字体
macOS用户需要注意字体名称的后缀:
服务器环境通常没有图形界面,需要手动安装字体。以Ubuntu为例:
bash复制# 安装常用中文字体
sudo apt install fonts-wqy-zenhei fonts-wqy-microhei fonts-arphic-ukai fonts-arphic-uming
然后在Python中配置:
python复制plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei'] # 文泉驿正黑
如果是在Docker容器中,需要确保字体文件被打包进镜像。在Dockerfile中添加:
dockerfile复制RUN apt-get update && apt-get install -y fonts-wqy-zenhei
当你需要确保在所有环境中使用统一字体时,最好的方法是打包字体文件随项目分发。假设我们有一个"SourceHanSansCN-Regular.ttf"字体:
python复制from matplotlib import font_manager
import matplotlib.pyplot as plt
# 添加字体目录到搜索路径
font_dirs = ['./fonts'] # 字体文件所在目录
font_files = font_manager.findSystemFonts(fontpaths=font_dirs)
for font_file in font_files:
font_manager.fontManager.addfont(font_file)
# 设置全局字体
plt.rcParams['font.family'] = 'Source Han Sans CN'
如果只想在特定图表中使用自定义字体,可以这样操作:
python复制from matplotlib.font_manager import FontProperties
my_font = FontProperties(fname='./fonts/SourceHanSansCN-Regular.ttf')
plt.figure()
plt.title('自定义字体标题', fontproperties=my_font)
plt.xlabel('默认字体X轴')
plt.ylabel('自定义字体Y轴', fontproperties=my_font)
这种方法特别适合需要混合使用多种字体的场景,比如中英文混排时使用不同的字体。
想知道你的环境支持哪些字体?试试这些方法:
python复制# 查看所有系统字体
from matplotlib.font_manager import fontManager
print([f.name for f in fontManager.ttflist if 'Songti' in f.name])
# Linux/macOS命令行查看中文字体
# fc-list :lang=zh family
设置字体优先级列表,当首选字体不可用时自动使用备选字体:
python复制plt.rcParams['font.sans-serif'] = [
'Source Han Sans CN', # 首选字体
'Microsoft YaHei', # Windows备选
'PingFang SC', # macOS备选
'WenQuanYi Zen Hei' # Linux备选
]
matplotlib支持五种基本字体样式:
可以通过rcParams配置默认样式:
python复制plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['SimSun'] # 宋体作为衬线字体
修改字体配置后如果没生效,可能是缓存问题。解决方法:
python复制import matplotlib
matplotlib.font_manager._rebuild() # 重建字体缓存
或者直接删除缓存文件(位置可以通过matplotlib.get_cachedir()查看)。
在Docker中除了安装字体,还需要设置环境变量:
dockerfile复制ENV MATPLOTLIBRC=/config
COPY matplotlibrc /config/
其中matplotlibrc文件包含你的字体配置:
code复制font.family : sans-serif
font.sans-serif : Source Han Sans CN, Microsoft YaHei, WenQuanYi Zen Hei
要在matplotlib中同时显示中文和数学公式:
python复制plt.rcParams['text.usetex'] = True
plt.rcParams['text.latex.preamble'] = r'\usepackage{ctex}' # 中文支持
plt.title(r'中文标题 $\alpha=\beta^2$') # 混合显示
最近在金融数据分析项目中,我们需要在CentOS服务器上生成包含中文的自动报表。解决方案是:
python复制plt.rcParams['pdf.fonttype'] = 42 # 确保PDF嵌入字体
plt.rcParams['ps.fonttype'] = 42
这套方案经过半年多的生产环境验证,在Windows开发机、MacBook Pro和Linux服务器上都能完美显示中文,生成的PDF文件也能在任何设备上正确查看。