背景
最近在Jupyter
里Matplotlib
绘制一些图表的时候,遇到一个很久没遇到的中文乱码问题,类似下图里的图例,中文变成了方块:
问题原因
以前使用Linux系统的时候,经常会遇到这个问题。通常的原因就是编码格式不支持或者使用的字体里没有中文导致。而Matplotlib
出现这个问题,就是因为其使用的字体里没有中文导致。
Matplotlib
默认使用的字体是一种衬线字体,叫做DejaVu。我们要规避这个问题,就是要把这个字体改掉。
解决办法
1. 找到合适的字体
字体的选择,有两个方案:
从互联网上下载自己喜欢的字体,安装到电脑上
从MacOS中查找包含中文的字体,直接拿来用
这里着重说一下第2条,如何在本机上找到合适的字体。我们可以通过下面这个脚本,打印出电脑上所有可用的字体,从中选择自己喜欢的即可。
1 | from matplotlib.font_manager import FontManager |
而我最终选择的字体是PingFang HK,这个字体是Apple官方在黑体的基础上开发的字体,中文的显示效果比较能接受。
2. 临时解决方案
在绘图时,我们可以通过rcParams
参数,设置单张图表使用的字体,如下:
1 | from matplotlib import rcParams |
3. 长久解决方案
如果我们不想每次画图的时候,都要写一下字体参数,则可以修改Matplotlib
的配置文件,让配置长久生效。
1. 查找配置文件的路径
由于Matplotlib
可能通过多种途径安装,如pip
,conda
等。其安装路径千差万别,配置文件的路径也有不同,需要我们通过一些途径找到。如下面这段代码:
1 | import matplotlib |
2. 修改字体配置
在配置文件中,我们可以找到font.family
变量,它可以设定为具体的文字名,如PingFang HK,也可以是官方预定义的几个枚举,如:
- ‘serif’ (e.g., Times),
- ‘sans-serif’ (e.g., Helvetica),
- ‘cursive’ (e.g., Zapf-Chancery),
- ‘fantasy’ (e.g., Western), and
- ‘monospace’ (e.g., Courier).
如果使用上面的枚举的时候,Matplotlib
会从其对应的字体数组中从前向后查找。这也是为什么默认字体是DejaVu的原因,因为其在所有数组的第一个。
修改后的配置如下:
1 | font.family: 'PingFang HK' |