This is a post which follows up my previous post on how to use Chinese characters with Matplotlib.
Introduction#
If we use some Unicode characters when plotting with Matplotlib, for example,
character ✹ (Unicode code point is
U+2739), you will find that the character
may not show up in the rendered image. The reason is simple: the default font
used by Matplotlib does not support this Unicode character.
In order to plot this Unicode character, we need to do two things. Firstly, we need to find a font which supports this character. Secondly, we need to tell Matplotlib to choose this font for rendering the character.
Find a valid font#
Since this character may not belong to a certain language. It is trickier to find which font supports it. According to post here, we can use the Python package fontTools to check if a character exists in a certain font.
First, we need to install fontTools. If you are using pip, use the following command to install fontTools,
pip install fonttoolsIf you are using conda, use
conda install -c conda-forge fonttoolsto install this package.
Then, we can use the following script to show a list of fonts which contain this Unicode character.
from fontTools.ttLib import TTFont
import matplotlib.font_manager as mfm
def char_in_font(Unicode_char, font):
for cmap in font['cmap'].tables:
if cmap.isUnicode():
if ord(Unicode_char) in cmap.cmap:
return True
return False
uni_char = u"✹"
# or uni_char = u"\u2739"
font_info = [(f.fname, f.name) for f in mfm.fontManager.ttflist]
for i, font in enumerate(font_info):
if char_in_font(uni_char, TTFont(font[0], fontNumber=0)):
print(font[0], font[1])The above script will print a list of font path along with their corresponding font names. All these fonts support the queried character. Sample output on my system is shown below:
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf DejaVu Sans
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf DejaVu Sans Mono
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf DejaVu Sans
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf DejaVu Sans
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf DejaVu Sans Mono
/home/jdhao/util/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf DejaVu Sans
/usr/share/fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf DejaVu Sans
/usr/share/fonts/dejavu/DejaVuSansCondensed-Bold.ttf DejaVu Sans
/usr/share/fonts/dejavu/DejaVuSansCondensed.ttf DejaVu Sans
/usr/share/fonts/dejavu/DejaVuSansCondensed-Oblique.ttf DejaVu Sans
/usr/share/fonts/gnu-free/FreeSerif.ttf FreeSerif
/usr/share/fonts/opensymbol/opens___.ttf OpenSymbolPlot this character#
In order to plot this character with Matplotlib, we need to use
FontProperties class in Matplotlib to find this font. Then we can use this
font in the plotting command:
import matplotlib.pyplot as plt
import matplotlib.font_manager as mfm
font_path = '/usr/share/fonts/gnu-free/FreeSerif.ttf'
prop = mfm.FontProperties(fname=font_path) # find this font
# use the font in plotting command
plt.text(0.5, 0.5, s=uni_char, fontproperties=prop, fontsize=20)
plt.show()In the above code, variable font_path is the path of a font supporting the
Unicode character.
We can also use the font name to look up a font,
import matplotlib.pyplot as plt
import matplotlib.font_manager as mfm
font_path = '/usr/share/fonts/gnu-free/FreeSerif.ttf'
prop = mfm.FontProperties(family='OpenSymbol')
plt.text(0.5, 0.5, s=uni_char, fontproperties=prop, fontsize=20)
plt.show()Output image is shown below
