matplotlib 无法显示中文字体的解决方法

时间:2024-03-02 08:01:21

转载自:https://www.cnblogs.com/taceywong/p/5468224.html

使用以下方法中的一种,添加中文字体后,在pyplot.legend方法中设置prop等于设置好的字体,在pyplot.xlabel中设置FontProperties等于新字体。

 

matplotlib的强大无需我去言说,但它对使用中文的我来说却有一点瑕疵,那就是——在默认状态下,matplotlb无法在图表中使用中文。

在网上查找了一些资料,发现matplotlib本身是支持Unicode的,只不过默认情况下matplotlib使用自带的字体,而自带的字体中没有中文字体。这样要它支持中文的思路就有了——给maplotlib添加中文字体。

思路1:用某种中文字体替换掉matplotlib的默认字体

这属于一种破坏性质的方法,不推荐。这样的方法,同样的代码无法在不同的环境中使用,每次更换环境你必须得重新"Hack"一次。我也没有使用这种方法。

思路2:使用matplotlib的字体管理器指定字体文件

matplotlib中有一个字体管理器——matplotlib.Font_manager,通过该管理器的方法——matplotlib.Font_manager.FontProperties(fname)可以指定一个ttf字体文件作为图表使用的字体。这样,只要我们传入Unicode字符串,我们就可以想用什么字体就用什么字体了。示例代码如下:

# coding:utf-8

from pylab import *
import random

myfont = matplotlib.font_manager.FontProperties(fname="Light.ttc")
mpl.rcParams[\'axes.unicode_minus\'] = False
t = arange(-5*pi, 5*pi, 0.001)
y = sin(t)/t
my_post = plt.plot(t, y)
plt.title(u\'matplotlib中文显示测试——Tacey Wong\',fontproperties=myfont)
plt.xlabel(u\'这里是X坐标\',fontproperties=myfont)
plt.ylabel(u\'这里是Y坐标\',fontproperties=myfont)

plt.show()

代码中第六行通过fname指定字体文件,第七行的作用是为了消除更换为unicode字体之后0、负数之类的显示异常。之后所有使用中文字体的地方只字符串都以u""的形式出现,并指定fontproperties属性为我们的指定的myfont就行了。该示例代码的图表生成结果如下:

这种办法的好处是想用什么字体,指出这个字体文件的路径名字就可以了。只要是ttf兼容的,都可以使用。

思路3:使用系统中安装的字体

前面说了,matplotlib一般使用的是非系统字体,我们在这里可以指定它使用我们系统中已经安装的某一个字体,这里我们需要的不是像“宋体、仿宋”这样的名称,也不是“xxx.ttf”这样的字体文件名称,二十需要我们的系统可以识别的字体名称。

Linux中可以使用命令——fc-list :lang=zh来查看我们系统安装的中文字体系统识别的名称,Droid Sans Fallback即为Ubuntu系统自带的一款中文字体,在这里我们使用这个字体作为matplotlib使用的系统字体。示例代码如下:

# coding:utf-8

def conf_zh(font_name):
    from pylab import mpl
    mpl.rcParams[\'font.sans-serif\'] = [font_name]
    mpl.rcParams[\'axes.unicode_minus\'] = False 

def run():
    from pylab import *
    import random

    t = arange(-5*pi, 5*pi, 0.001)
    y = sin(t)/t
    my_post = plt.plot(t, y)
    plt.title(u\'matplotlib中文显示测试——Tacey Wong\') 
    plt.xlabel(u\'这里是X坐标\')
    plt.ylabel(u\'这里是Y坐标\')

    plt.show()
if __name__ == "__main__":
    conf_zh("Droid Sans Fallback")
    run()

这样的方法有一个好处就是可以将指定字体的部分单独提取作为一个函数,每次绘图之前调用一次就行了,不用每次都指定fontproperties属性。

该示例的图表生成结果如下:

如果不是系统自带的字体安装之后是否可以用这种方法呢?答案是肯定的,需要的只是把传入的名字改成自己安装的字体系统所识别的名字,也就是将conf_zh("Droid Sans Fallback")改为conf_zh("自己安装的字体系统所识别的名字")。下面就是使用一个自安装的字体的生成结果(conf_zh("Li Xuke Comic Font")):

这种方法的好处是不需要额外的配置fontproperties属性,配置一次,后续代码和用英文字符串没什么两样(如果不需要配置字体的其他属性的话,这种方法很方便)

总结

后两种方法各有有利之处。更多的字体配置可以可以修改matplotlib的配置文件。用下面的代码查看该配置文件的位置在哪里:

import matplotlib
print matplotlib.matplotlib_fname()

该命令会返回配置文件地址,如,在我的机子上返回了下面的结果

/etc/matplotlibrc

matplotlibrc即为matplotlib的配置文件,里面不只有字体配置,感兴趣的话可以看一下。下面是部分配置项截图:

有兴趣的可以查看一下里面的内容。