完美解决matplotlib画图中文显示问题

相信有很多人曾经被matplotlib画图的中文显示问题所困扰,包括我自己。每次生产环境发生改变,都会遭遇到这个问题,然后需要花大量的时间在它上边。最可气的是每次遇到的问题不一定一样,上一次使用的方法不一定适用。网上的教程很多,但没有看到一个完整的、必杀的解决方案。

我在花了大量时间进行多次尝试之后,总结出了一套流程,截止目前我遇到过的所有的不同环境下(Linux + Mac)的matplotlib中文显示问题都得到了完美解决,因此整理出来分享给大家,希望能让大家少走弯路,把时间花在更有价值的地方。

刚好我购置了一台腾讯云的服务器,我们就拿它为例,看一下如何配置。

首先我们安装好Python3+matplotlib,然后进入Python,画一张图来看看效果:

import matplotlib.pyplot as plt
plt.plot([1,3,2,4], '--r')
plt.title(u'测试')
plt.savefig('temp.png')
-w460

可以看到虽然我们为title设置了中文“测试”,但实际上显示出来的却是两个方框。好,那我们就开始解决这个问题。

第一步:确认系统字体

我们在命令行中通过fc-list :lang=zh来查看下系统是否有安装中文字体。

# root @ VM_0_16_centos in ~ [14:20:29]
$ fc-list :lang=zh

# root @ VM_0_16_centos in ~ [14:22:01]
$

我们看到输出为空,这说明我们的Linux系统暂时没有安装中文字体,我们需要进行安装。老版本有很多种安装方法,有一些甚至需要root权限,这一点很不友好。因为很多朋友的服务器是公司提供的,出于安全考虑,普通技术员工并没有root权限。

好在现在绝大多数的linux版本都已经可以非常快速地通过复制文件的方式来安装字体了。

我们先下载喜欢的中文字体,比如黑体、楷体和微软雅黑。下载好之后,我们将文件上传到服务器,并移动到个人目录下的.fonts文件夹内。

然后,我们再检查一下:

# root @ VM_0_16_centos in ~ [14:27:46]
$ fc-list :lang=zh
/root/.fonts/msyh.ttf: 微软雅黑,Microsoft YaHei:style=Regular
/root/.fonts/simhei.ttf: 黑体,SimHei:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/root/.fonts/simkai.ttf: 楷体_GB2312,KaiTi_GB2312:style=Regular

可以看到,我们已经成功地将三个中文字体安装到了系统中,是不是很简单快速?

第二步:安装matplotlib字体支持

接下来我们要在matplotlib中安装中文字体(这一步在有些教程里是不需要的,但是时灵时不灵,我们最好也安装一下。),这一步需要我们先确认字体的安装目录。

In [9]: import matplotlib as mpl

In [10]: mpl.matplotlib_fname()
Out[10]: '/usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc'

我们看到了matplotlib的配置文件的地址,记住这个地址,后边修改配置时要用到。现在我们用它来定位字体文件夹。我们进入配置文件所在目录:

# root @ VM_0_16_centos in ~ [14:41:22] C:1
$ cd /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data/

# root @ VM_0_16_centos in /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data [14:41:24]
$ ll
总用量 52K
drwxr-xr-x 5 root root 4.0K 11月 30 14:03 fonts
drwxr-xr-x 2 root root 4.0K 11月 30 14:03 images
-rw-r--r-- 1 root root  33K 11月 30 14:03 matplotlibrc
drwxr-xr-x 3 root root 4.0K 11月 30 14:03 sample_data
drwxr-xr-x 2 root root 4.0K 11月 30 14:03 stylelib

# root @ VM_0_16_centos in /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data [14:41:25]
$ cd fonts

# root @ VM_0_16_centos in /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data/fonts [14:41:29]
$ ll
总用量 12K
drwxr-xr-x 2 root root 4.0K 11月 30 14:03 afm
drwxr-xr-x 2 root root 4.0K 11月 30 14:03 pdfcorefonts
drwxr-xr-x 2 root root 4.0K 11月 30 14:03 ttf

# root @ VM_0_16_centos in /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data/fonts [14:41:31]
$ cd ttf

# root @ VM_0_16_centos in /usr/local/lib64/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf [14:41:33]
$ ll
总用量 6.7M
-rw-r--r-- 1 root root  26K 11月 30 14:03 cmb10.ttf
-rw-r--r-- 1 root root  21K 11月 30 14:03 cmex10.ttf
-rw-r--r-- 1 root root  32K 11月 30 14:03 cmmi10.ttf
-rw-r--r-- 1 root root  26K 11月 30 14:03 cmr10.ttf
-rw-r--r-- 1 root root  20K 11月 30 14:03 cmss10.ttf
-rw-r--r-- 1 root root  29K 11月 30 14:03 cmsy10.ttf
-rw-r--r-- 1 root root  28K 11月 30 14:03 cmtt10.ttf
......

好了,接下来我们将刚才的字体文件复制过来即可。

第三步:修改matplotlib配置文件

我们先关闭所有的Python程序,包括Python、IPython、Jupyter等,因为一会儿修改完之后需要清空缓存并重启程序生效。

还记得刚才的matplotlibrc的地址吧,我们用趁手的文本编辑器打开它,去掉如下三行开头的注释符,并在font.sans-serif的取值中,将我们刚才三个字体的英文名称添加到最前边。英文名称在我们刚才使用fc-list :lang=zh时可以看到。

axes.unicode_minus  : True   
font.family         : sans-serif
font.sans-serif     : Microsoft YaHei, SimHei, KaiTi_GB2312, DejaVu Sans, Bitstream Vera Sans, ...

保存退出。

这一步需要注意的是,如果你的系统中存在多个Python环境,那一定要确保你安装的字体以及修改的配置文件是你要使用的那一个环境中的。

第四步:删除缓存

不删除缓存的话,在代码中指定字体文件或字体名称理论上也可以使用,但这样太麻烦 ,我们要解决就解决彻底。

一般情况下,缓存在~/.cache/matplotlib目录下,但也有些会在~/.matplotlib目录下(我的Mac是这样的),不管在哪里,我们直接清除掉这个目录即可。

rm -rf ~/.cache/matplotlib

或者

rm -rf ~/.matplotlib

第五步:重启Python程序

现在我们重新打开我们的Python程序,检查一下是否已经好了。

import matplotlib.pyplot as plt
plt.plot([1,3,2,4], '--r')
plt.title(u'测试')
plt.savefig('temp.png')
-w460

大功告成,我们的title成功地显示出来了。

第六步:针对Python2的补充

另外说一点,由于Python2默认的编码方式并不是UTF-8,因此在Python2中,我们要在字符串之前添加u,强制将字符串以Unicode方式编码。如上例,在Python2中,我们应该使用u"测试"

以上就是我梳理的完整的解决流程,如有严格按照此流程操作仍不能解决的,可以联系我,我们一起探讨。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容