Zodiac Wang
  • Home
  • Categories
  • Tags
  • Archives

让Matplotlib正确显示中文


用 Matplotlib 画图时中文无法显示,遂解决之

本方法只适用于 Linux 环境

Matplotlib 无法显示中文这个问题由来已久,官方一直没有解决,只能自己解决啦。

Table of Contents

  • 1  安装中文字体
  • 2  将字体文件拷贝到 Matplolib 字体文件夹
    • 2.1  可选操作
  • 3  方案1-通过 rc.Params 指定字体
  • 4  方案2-通过路径指定字体
  • 5  总结
  • 6  可能需要的操作

安装中文字体¶

可以从这个 repo 安装

git clone https://github.com/tracyone/program_font 
cd program_font 
./install.sh

安装完字体之后 /usr/share/fonts 目录下会多出很多字体。这只是给 Ubuntu 系统安装了字体,但 Matplotlib 还是不能使用这些字体,需要将字体文件拷贝到 Matplolib 字体文件夹

将字体文件拷贝到 Matplolib 字体文件夹¶

检测 Matplotlib 字体文件夹

In [1]:
import matplotlib
matplotlib.matplotlib_fname()
Out[1]:
'/home/nwpu/anaconda3/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc'

Matplotlib 的字体文件夹应该在同级目录,即 /home/nwpu/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts

从 /usr/share/fonts 中找一个中文字体的 ttf 文件拷贝到 /home/nwpu/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts 文件夹

可选操作¶

删除当前用户matplotlib 的缓存文件(如果没有直接进入第四步)

$cd ~/.cache/matplotlib
$rm -rf *.*

通过以下脚本检测 Ubuntu 和 Matplotlib 都可用的字体

In [2]:
from matplotlib.font_manager import FontManager
import subprocess
fm = FontManager()
mat_fonts = set(f.name for f in fm.ttflist)
#print(mat_fonts)
output = subprocess.check_output(
    'fc-list :lang=zh -f "%{family}\n"', shell=True) # 获取字体列表
output = output.decode('utf-8')
#print(output)

zh_fonts = set(f.split(',', 1)[0] for f in output.split('\n'))
available = mat_fonts & zh_fonts
print('*' * 10, '可用的字体', '*' * 10)
for f in available:
    print(f)
********** 可用的字体 **********
Yahei Mono
YaHei Consolas Hybrid
Droid Sans Fallback

方案1-通过 rc.Params 指定字体¶

In [3]:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

font_name = "YaHei Consolas Hybrid"
mpl.rcParams['font.family']= font_name # 指定字体,实际上相当于修改 matplotlibrc 文件 只不过这样做是暂时的 下次失效
mpl.rcParams['axes.unicode_minus']=False # 正确显示负号,防止变成方框

t = np.linspace(0, 2*np.pi, 1000, endpoint=False)
y = np.sin(t)
fig, ax = plt.subplots()

ax.set_xlabel(u"text for t轴")
ax.set_ylabel(u"text for y轴")
ax.set_title(u"t和y对应关系")
ax.plot(t,y)
plt.savefig("data/save.png", bbox_inches='tight', dpi = 1000)


plt.text(0.5, 0.5, s=u'测试')
plt.show()

以上操作暂时更改 Matplotlib 的字体选项,只在本 kernel 中有效

若想永久更改 Matplotlib 所使用的字体,可以直接修改matplotlibrc文件,路径为 matplotlib.matplotlib_fname() 的返回值即 /home/nwpu/anaconda3/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc

具体修改以下几项

font.family         : sans-serif        
font.sans-serif     : SimHei, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif # 在其中添加中文字体名
axes.unicode_minus  :False,#作用就是解决负号'-'显示为方块的问题

方案2-通过路径指定字体¶

通过路径指定字体可以指定系统内任意字体,而不需要是 matplotlib 字体文件夹内的字体

In [4]:
import matplotlib.font_manager as mfm

font_path = "/usr/share/fonts/MyFonts/YaHei.Consolas.1.11b.ttf"
prop = mfm.FontProperties(fname=font_path)

t = np.linspace(0, 2*np.pi, 1000, endpoint=False)
y = np.sin(t)
fig, ax = plt.subplots()

ax.set_xlabel(u"text for t轴")
ax.set_ylabel(u"text for y轴")
ax.set_title(u"t和y对应关系")
ax.plot(t,y)
plt.savefig("data/save.png", bbox_inches='tight', dpi = 1000)


plt.text(0.5, 0.5, s=u'测试')
plt.show()

总结¶

  1. 为 Ubuntu 系统安装中文字体
  2. 将中文字体拷贝到 Matplotlib 字体文件夹
  3. 在代码中指定一个可用的字体

可能需要的操作¶

from matplotlib.font_manager import _rebuild

_rebuild() #reload一下

References:

  • A Gentle Guide on How to Use Chinese Characters With Matplotlib

  • « Python多进程
  • [分享]Box-X一款提高 Python 代码开发和调试效率神器 »

Published

10 25, 2018

Category

posts

Tags

  • Matplotlib 10
  • Python 16

Contact

  • Zodiac Wang - A Fantastic Learner
  • Powered by Pelican. Theme: Elegant