A few days ago, I found that Matplotlib can not show some Unicode characters (some Chinese characters) using its default settings. In the rendered output image, Chinese characters are shown as blank boxes. After reading a lot of posts on this issue, I am finally clear about how to use Unicode characters properly in Matplotlib.1
The reason that Chinese characters are shown as boxes is that Matplotlib’s default font does not support Chinese. In order to use Chinese, we need to tell Matplotlib to use a font which supports Chinese. Or, more directly, we can provide the path of a Chinese font to Matplotlib.
This post assumes that
fc-list is available on your system. If this is not
the case, you should first install fontconfig.
On Linux, fontconfig is usually pre-installed, so no need to worry. On Windows,
you can install MiKTeX or TeX Live
in order to use
Specify Chinese font by name
The first way to use Chinese is to give a valid font name to Matplotlib. Before going on to the next step, make sure that there are Chinese fonts on your system. If that is not the case, or if you want to try a new Chinese font, for example, Source Han Serif recently released by Google and Adobe2.
Find valid Chinese fonts
Matplotlib provides the FontManager
class to deal with fonts. This class has an attribute
ttflist which provides
a list of font files indexed by Matplotlib. We can also get each font’s name
easily from this list. The problem is that we do not know which of these
fonts support Chinese.
This is when fc-list comes to help. This
command can help us find Chinese fonts installed on the system. The command
fc-list :lang=zh will list all the available Chinese fonts. But it should be
noted that not all Chinese fonts are indexed by Matplotlib. Some of the
ttc font files can not be used by Matplotlib.
So we need to find the intersection of available Chinese fonts and fonts indexed
Use a font
After we have found a valid Chinese font indexed by Matplotlib, we can tell Matplotlib to use it by changing the Matplotlib rc in our script. In this way, all the following plotting command will use the new font. Suppose that you have installed “STKaiti” on your system, the following code will use it to render Chinese:
import matplotlib as mpl font_name = "STKaiti" 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()
In the above code,
font_name can be the name of any valid Chinese font. If
you just want to use a Chinese font for a particular command, you can directly
specify the font’s name in the plotting command:
plt.text(0.5, 0.5, s=u'测试', fontname=font_name)
This is my preferred way of using Chinese fonts with Matplotlib.
Specify Chinese font by path
In order to use any font on our system, we should try the second way — directly give a font’s path to Matplotlib. The code is like this:
import matplotlib.font_manager as mfm import matplotlib.pyplot as plt font_path = "/usr/share/fonts/custom/simhei.ttf" prop = mfm.FontProperties(fname=font_path) plt.text(0.5, 0.5, s=u'测试', fontproperties=prop) plt.show()
font_path is the path to a Chinese font on your system.
Both the two ways are easy to follow. You can choose whichever suits your need best. For the complete code and also info on how to find available Chinese fonts on your system, please refer to the code on this repo.
- The first way
- This page shows how to use the first method.
- This SO post also use the second way.
- Matplotlib official example on the second way.
- How to use the fontconfig pattern
License CC BY-NC-ND 4.0