Hello,
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,
Abe
–
System
- Ubuntu 18.04
- Python 3.6.8
- Matplotlib 3.1.2
Technical Overview, in More Detail
- I am using a
.mplstyle
file to try to use a custom font(s) in my plots - I am using the
font.family
parameter in the file - By custom, I mean that they are not provided in
matplotlib
's default collection - the font(s) I have tried are
ttf
- the font(s) I have tried are installed, i.e. I can see them in different programs
- I am running
matplotlib
from withinjupyter
1. font.family
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
F
is in the same folder as the font family that is working - run
chmod 777
on theF
family folder - confirmed that my OS is picking
F
up, 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 findSystemFonts
(assuming 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
ttf
file 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.