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 fonttools
If you are using conda, use
conda install -c conda-forge fonttools
to 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 OpenSymbol
Plot 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