最近在python使用matplotlib以及plotnine绘图时,发现绘制的图表无法正常显示中文。花了好一阵子才找到解决方案。记录在此供参考。
一、Matplotlib显示中文的处理方案
首先导入matplotlib模块,绘制一个包含中文的图像,看看是否能正常显示“测试”两个字。
import matplotlib.pyplot as plt
plt.text(0.5, 0.5, s=u'测试')
plt.show()
试验发现无法正常显示,中文部分变成了两个空白方块。
为了让matplotlib正常显示中文,需要人工设置matplotlib支持的中文字体作为默认字体。为了实现这一目标,实际上需要完成三个步骤:
1)找到matplotlib支持的所有字体的名称列表。
2)在字体名称列表中找出中文字体。
3)人工设置中文字体为默认字体。
接下来分步完成上述三个步骤。
步骤一:找到matplotlib支持的所有字体的名称列表。代码如下:
import matplotlib.font_manager
[f.name for f in matplotlib.font_manager.fontManager.ttflist]
得到类似于下面这种列表:
步骤二:在列表中找出中文字体。
其实中文字体从名称上就可以很明显地识别出来。比如我电脑中的黑体字名称是"Heiti TC", 宋体字名称是"Songti SC"。不同电脑的情况可能都不一样。
步骤三:把中文字体设置为默认字体(下面的代码是把宋体Songti SC设置为默认代码)
import matplotlib as mpl
font_name = "Songti SC"
mpl.rcParams['font.family']=font_name
mpl.rcParams['axes.unicode_minus']=False # in case minus sign is shown as box
这样设置之后,再次测试:
plt.text(0.5, 0.5, s=u'测试')
plt.show()
发现matplotlib可以正常显示中文字体了。
二、Plotnine正常显示中文的处理方案
如果之前习惯用R绘图的朋友,可能会比较愿意使用Python中的plotnine模块绘图。这是因为plotnine的语法和R中的ggplot2很相似。首先用plotnine模块做个实验看看能否正常显示中文:
#!pip install plotnine
from plotnine import *
(ggplot()+ annotate('text', x=0.5, y=0.5, label='测试',size=8)
)
同样发现无法正常显示中文。原本应该显示中文的地方变成了两个方块。
为了使Plotnine正常显示中文,需要额外在theme中把字体设置为中文字体。值得注意的是,plotnine支持的字体就是matplotlib支持的字体。因此可以先在matplotlib中查找支持的中文字体,然后在plotnine中的theme下设置text=element_text(family="某个中文字体名称")。前面我们已经知道了"Songti SC"以及“Heiti TC"都是支持的中文字体,因此设置为二者之一即可。具体代码如下:
from plotnine import *
(ggplot()+ annotate('text', x=0.5, y=0.5, label='测试',size=8)+ theme(text=element_text(family="Heiti TC"))
)
这样设置后,发现可以正常显示中文了:
参考资料如下:
A Guide on Using Unicode Characters in Matplotlib - jdhao's digital space
Using ggplot in Python: Visualizing Data With plotnine – Real Python
xlab,ylab,ggtitle cannot use Chinese character · Issue #84 · has2k1/plotnine · GitHub
python - How can i get list of font family(or Name of Font) in matplotlib - Stack Overflow