Matplotlib在Mac M1芯片绘图中文显示异常问题
最近需要用到matplotlib.pyplot库使用Python对一些数据进行绘图操作,
发现在Apple M1 芯片的Mac上, 中文显示异常, 写篇博文记录一下解决过程, 直达链接
环境情况
| 环境 | 配置 |
|---|---|
| 硬件及操作系统 | Mac 2021 with M1 Pro chip MacOS Monterey 12.4 ![]() |
| IDE | Pycharm 2022.1.1
Professional![]() |
| Python环境 | Anaconda 2.2.0
![]() Python 3.9.12 |
| Matplotlib版本 | matplotlib==3.5.2 |
问题展现
使用plt绘图的时候, 如果图表中含有中文会显示异常, 变为□,
如下图
解决过程
修改支持中文的字体 plt.rcParams['font.sans-serif']=['SimHei']
解决matplotlib中文显示问题Font family [sans-serif] not found_ve2102388688的博客-CSDN博客_font.sans-serif
1 | plt.rcParams['font.sans-serif']=['SimHei'] |
结果: 失败
1 | findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans. |
提示SimHei字体未找到
修改添加字体支持
结果: 未尝试
用法过于复杂, 不利于复现, 并且如果代码迁移到其他IDE或环境需要重新设置
修改支持中文的字体 plt.rc("font",family="AR PL UKai CN")
【python】matplotlib绘图显示不了中文,且没有SimHei、FangSong等字体_-徐徐图之-的博客-CSDN博客_python simhei
1 | plt.rc("font",family="AR PL UKai CN") |
结果: 失败
1 | findfont: Font family ['AR PL UKai CN'] not found. Falling back to DejaVu Sans. |
提示AR PL UKai CN字体未找到
导入pylab包
1 | from pylab import * |
结果: 失败
1 | findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans. |
提示SimHei字体未找到
使用matplotlib.rc修改默认字体
1 | # 预设字体格式,并传给rc方法 |
结果: 失败
1 | findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans. |
提示SimHei字体未找到
使用font_manager类
1 | import matplotlib.pyplot as plt |
结果: 未尝试
理论上与rc或pylab包方式一样, 无法解决字体不存在的问题
修改支持中文的字体 plt.rcParams['font.sans-serif'] = ['Heiti TC']
python - How to plot a figure with Chinese Characters in label - Stack Overflow
1 | plt.rcParams['font.sans-serif'] = ['Heiti TC'] |
结果: 成功
该字体默认存在, 可以正确显示中文字符
图片保存空白
执行plt.savefig(1.jpg)后, 图片显示空白,
问题出在plt.show()之后保存, 会新建一个空白画板,
因此需要先执行plt.savefit()再执行plt.show()即可解决
【Python】解决使用 plt.savefig 保存图片时一片空白_secsilm的博客-CSDN博客_plt.sav
Docker容器内中文异常
🆙 2022-07-13 15:50:28
上面的方法本地部署是可以用的, 但是放到容器中就不行了, 容器中缺少字体支持
通过阅读知乎1的答案,
进入容器查看一下mathplotlib的默认字体
1 | # 查询当前系统所有字体 |
上面是我在python:3.9-slim的基础镜像中执行的结果,
通过知乎2的另一篇文章确认:
没有能支持中文的字体, 其中推荐了以下几类字体
1 | goodfont=[ |
个人觉得SimHei是一个不错的选择, 而且很容易下载到👉🏻SimHei免费字体下载
- 英文字体免费下载尽在字体家
阅读了简书3和CSDN4的博文,
提示可以通过添加font_manger.FontProperties(fname=<FONT_PATH.ttf>)实现自定义字体的方法
1 | import matplotlib.font_manager as ftm |
上面的代码会报错
legend不支持fontproperties参数, 修改一下代码
1 | #plt.legend(['最高温度', '最低温度'], fontproperties=font_props) |
图片可以显示了, 不过图例不出意外的乱码了
这个确实解决了一部分问题, 参考了一下博客园5的博文,
执行mathplotlib.mathplotlib_fname(),
可以拿到rc文件的路径
既然我要在容器里用, 直接把ttf放过去也不失为一种解决方案
上面的图显示的ttf文件与python执行显示的mathplotlib字体一致, 确定该目录就是存放字体的路径, 直接在dockerfile里添加一行
1 | RUN mv /app/utils/weather_forcast/SimHei.ttf /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/ |
构造一个函数用于解决中文乱码
1 | def _fix_chinese_chars(): |
添加后测试, 问题解决~


