搜 索

matplotlib 正常显示中文教程,font_manager 报错解决,RuntimeWarning: Glyph 20195 missing from current font. 解决方案

  • 7k阅读
  • 2021年02月16日
  • 0评论

matplotlib 因为是外国人开发的,默认不支持中文标签等的显示。需要我们做一些事情来支持。那么如何支持中文呢?首先我们用 font_manager 的方式来看看:

# matplotlib 只显示英文,无法显示中文,需要修改 matplotlib 的默认字体
# 通过 matplotlib 下的 font_manager 可以解决

# 两个小时内的每分钟跳动变化
from matplotlib import pyplot as plt
import random
x = range(0, 120)
y = [random.randint(10, 30) for i in range(120)]

plt.figure(figsize=(20, 8), dpi=80)
plt.plot(x, y)

# 加坐标轴信息
'''另外一种写法
查看 Linux、Mac 下支持的字体
        终端执行: fc-list
        查看支持的中文(冒号前面有空格) fc-list:lang=zh
查看 Windows 下的字体:“C:\Windows\Fonts”

可以自己下载字体文件(xxx.ttf),然后双击安装即可
# my_font = font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc', size=18)
# plt.ylabel("天气", fontproperties=my_font)
'''

from matplotlib import font_manager
my_font = font_manager.FontProperties(fname='C:\Windows\Fonts\simhei.ttf', size=18)
# rotation 将字体旋转 45 度
# xlabel 是画横轴的总体坐标轴名,不是刻度标签哦。而 ylabel 则是对应纵轴的
plt.xlabel("时间", rotation=45, fontproperties=my_font)
plt.ylabel("次数", fontproperties=my_font)

# 设置标题
plt.title('每分钟跳动次数', fontproperties=my_font, color='red')

plt.show()

其中一次运行结果:

262-1.png

多标签时中文字体显示失败怎么办?

当中文标签变多时,比如在弄一个柱状图,每个柱子都是中文的情况下,在某些电脑使用 font_manager 的方式配置字体的时候发现只有第一个柱子的标签的中文显示正常,其他的都显示不正常,显示各种小方框(非所有电脑,有的电脑会这样)。

一般会报这样的错误:RuntimeWarning: Glyph 20195 missing from current font.

262-2.png

这是怎么回事呢?研究了比较久还是没有找到答案。网上也基本找不到别人有这个问题的记录。不过如果遇到这种情况,我们有两种别的方式来解决。

临时方案

这种方案需要每次编写代码时都加上,属于临时解决方案。首先确定你的电脑里已经安装好了对应的中文字体。比如我们以黑体(SimHei)为例。我们可以使用 rcParam 属性来解决。同时,我们也可以同时设置另一个参数,用来正常显示负号。改变之后的代码如下:

# matplotlib 只显示英文,无法显示中文,需要修改 matplotlib 的默认字体

# 两个小时内的每分钟跳动变化
from matplotlib import pyplot as plt
import random

#==============================================
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签,黑体的 name 为 SimHei
plt.rcParams['font.size'] = 16  # 设置字体大小
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号,跟是否显示中文没关系,你可以考虑加或不加
#==============================================

x = range(0, 120)
y = [random.randint(10, 30) for i in range(120)]

plt.figure(figsize=(20, 8), dpi=80)
plt.plot(x, y)

# rotation 将字体旋转 45 度
plt.xlabel("时间", rotation=45)
plt.ylabel("次数")

# 设置标题
plt.title('每分钟跳动次数', color='red')

plt.show()

显示效果:

262-3.png

有的同学会好奇,你这个 SimHei 是哪里来的呢?其实是约定俗成的。有的常见的网上都能找得到。如果找不到呢?我们可以到系统里面去查看。当第一次运行画图代码的时候,matplotlib 会自动生成字体缓存。我们可以在 python shell 中运行代码查看本机的缓存保存路径:

>>> import matplotlib
>>> print(matplotlib.get_cachedir())

以 windows 为例,通常情况下,返回的路径为:C:\Users\你的用户名\.matplotlib。这个就是缓存路径了,打开这个文件夹,即可找到缓存文件,比如我这里的文件名为 fontlist-v330.json,然后你需要搜索你的字体文件的文件名,比如在 windows 中,字体文件的路径一般是为:C:\Windows\Fonts,然后找到你要用的字体文件,右键查看属性,点击安全选项卡,即可看到字体文件的文件名了。将文件名在缓存文件中搜索,搜到之后,查看 name 的值即为我们在代码中要写的 name 的值。

262-4.png

还有一点需要注意的是,有部分中文字体的文件名,不是全英文的,如果包含中文的文件名的话,在这个缓存文件中是以 unicode 的形式存在的,比如 21克拉的心.ttf

262-5.png

一劳永逸方案

除了每次画图都要写代码的方式之外,我们还有一劳永逸的办法。在同一台电脑中搞过一次之后,下次这台电脑在运行相关代码时,则不需要编写对应代码来使用中文字体了。

首先我们需要获取到我们要用的字体文件,比如 simhei.ttf,如果你电脑安装有,你可以到系统字体里面复制 ttf 文件出来。如果没有,到网上下载即可。

然后我们需要获取 matplotlib 的字体库存放的位置,运行下述代码:

>>> import matplotlib
>>> print(matplotlib.matplotlib_fname())

结果:
E:\ProgramFiles\anaconda\lib\site-packages\matplotlib\mpl-data\matplotlibrc

我这里是安装了 anaconda 的,则会返回对应的路径地址。这返回的是一个配置文件的地址。我们不要直接访问该地址,而要访问前面那一截:E:\ProgramFiles\anaconda\lib\site-packages\matplotlib\mpl-data。这是一个文件夹。接下来我们把 simhei.ttf 文件复制到 E:\ProgramFiles\anaconda\Lib\site-packages\matplotlib\mpl-data\fonts\ttf 这个文件夹中。(如果你的电脑地址跟我不一样,对应的找即可,记得举一反三哦)

完成后,使用记事本编辑工具打开 E:\ProgramFiles\anaconda\lib\site-packages\matplotlib\mpl-data\matplotlibrc 这个文件,发现是一个文本文件。在里面找到下面的内容并修改:

# font.sans-serif: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
改为:
font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif

# font.size:    10.0
改为(这个也可以不改,这是修改默认的字体大小):
font.size:    16.0

# axes.unicode_minus: True
改为(跟中文字体没关系,这是为了正常显示负号的):
axes.unicode_minus: False

修改完成后保存文件。

这里还没完成,你还需要删除缓存文件,前面我们讲过,缓存文件夹为 C:\Users\你的用户名\.matplotlib。请将该文件夹整个删除,即可删除缓存。

重启 python 或 jupyter 并运行画图代码,发现不需要编写使用中文字体的参数,即可正确显示中文字体!

补充说一句,当使用一劳永逸的方式将字体配置好之后,如果在实际使用的时候需要对字体进行个性化定制,比如修改使用别的字体或者修改字体大小的,可以参考前面临时方案的方式进行加代码配置即可哦。

评论区
暂无评论
avatar