I am a
matplotlib user of several years who is now getting ready to publish an open-source analysis project. We have been leveraging the Python data ecosystem for this project, with
matplotlib as our go-to library for producing visualizations. However, in trying to use my company’s particular font in the titles and labels of my MPL charts, I’ve run into issues, which I’ll try to do a decent job of summarizing below.
The below points fall into some combination of: question, comment, and ahh!? and I’m wondering whether I’m being an idiot or whether there are actually some issues within this layer of
matplotlib. I would really like to make deeper use of MPL but am hitting my head against the wall on this font stuff - any feedback, helpful pointers, emotional support etc. would be greatly appreciated.
Happy new year,
- Ubuntu 18.04
- Python 3.6.8
- Matplotlib 3.1.2
Technical Overview, in More Detail
- I am using a
.mplstylefile to try to use a custom font(s) in my plots
- I am using the
font.familyparameter in the file
- By custom, I mean that they are not provided in
matplotlib's default collection
- the font(s) I have tried are
- the font(s) I have tried are installed, i.e. I can see them in different programs
- I am running
Based on the sample file that I found, it seems like
font.family should be a key into a variety of different fonts within a particular font family, right? Well, it appears that that is only the case when making use of the included fonts, as there seems to be a set of hard-coded sub-keys for indexing into a family’s available fonts.
Is it just me, or does that seem silly? I have seen people hacking this, e.g. something like setting the
"sans-serif" key in
rcParams to equal a list of fonts from a custom family, but this seems like a bad approach. Aside from the fact that this is far from idiomatic, is misleading, etc., I have a number of different notebooks that I’m producing plots in and I’d much rather set the font once in a config file than copy and paste the same, misleading
rcParams hack in a number of different places.
2. Font Priority
Considering 1. above, I cannot pick a particular font from the family that I want, and am instead at the whim of MPL’s internal prioritization, which seems to be just grabbing the last item from the list of available
.ttf files in the family’s directory, yielding ultra-thin, as opposed to regular, the latter of which I would presume would be the default selection.
The way that I dealt with this was to just only put the regular font in the family’s folder in
/usr/share/fonts/truetype/, which for obvious reasons is not what I’d like to be doing.
3. Valid Font Not Being Picked Up
This is the issue that has left me the most stumped, i.e. this is what left me so desperate as to leave a complain-y mess of semi-nonsense on a public discussion board on a Monday night!
I’ve actually been experimenting with two different font families, each of which comes in its own directory. The first came from Google Fonts, and I can get it into
matplotlib using what I mentioned above in 2., i.e. putting just the regular version into the family directory. The second, which I’ll refer to as
F, came from my graphic designer, and I for the life of me cannot figure out why MPL can’t see it.
Here are some steps that I’ve taken:
- ensured that
Fis in the same folder as the font family that is working
chmod 777on the
- confirmed that my OS is picking
Fup, which should mean that I installed it correctly
To be sure, I ran
fc-cache -fv and verified that the the new family was cached, and I’ve been resetting my MPL cache with
rm -rf ~/.cache/matplotlib after refreshing my system’s font cache. I even ran a
fc-cache --really-force trial to be sure the
chmod-ing was picked up, and I even even restarted my notebook kernel, and even my machine, each multiple times, to make sure all was kosher.
On top of that, I can see the font in
name is the font name I’m after):
import matplotlib.pyplot as plt from matplotlib import font_manager as fm, rcParams sum([ name in f for f in fm.findSystemFonts(fontpaths=None, fontext='ttf') ]) # this produces 18
And MPL can see this collection of files, too - the following works fine (FYI this code comes from an official example):
prop = fm.FontProperties(fname=path_to_my_font) fig, ax = plt.subplots() ax.set_title('This is a special font', fontproperties=prop)
But, I am getting issues when I try to access via the family name as such - passing the following to
fontproperties produces a warning about the font family not being found:
prop = fm.FontProperties(family=name)
So, I am very confused about why MPL:
- can see the font family’s folder
- can access a
ttffile within that folder, if a file path is passed
- can not access the font family via the font family’s name
If anyone has any ideas, I’d be grateful to hear them.