22

There is a custom font in my app

app_path='/home/user1/myapp'
fname='/home/user1/myapp/font/myfont.ttf'

To setup globlal font to matplotlib,the docs said like this:

plt.rcParams['font.sans-serif']=['xxx font']

But it only works when the font already in system font path,and I have to use my custom font in my app path '/home/user1/myapp/font/myfont.ttf'

I know there is a way like this:

fname='/home/user1/myapp/font/myfont.ttf'
myfont=fm.FontProperties(fname=fname)
ax1.set_title('title test',fontproperties=myfont)

But that is not what I want,I don't want to set 'fontproperties' all the time,because there are some much code to change

dindom
  • 583
  • 2
  • 4
  • 17
  • use a font manager, that's what they're for. While they run they can make fonts available as system fonts on the fly, so you can keep your fonts organised logically on disk, while using them in your applications as if they're system-level installed. – Mike 'Pomax' Kamermans Feb 27 '16 at 17:28
  • you mean :myfont=fm.FontProperties(fname=fname) ? – dindom Mar 01 '16 at 02:18

3 Answers3

32

Solved the problem like this:

import matplotlib.font_manager as font_manager

font_dirs = ['/my/custom/font/dir', ]
font_files = font_manager.findSystemFonts(fontpaths=font_dirs)
font_list = font_manager.createFontList(font_files)
font_manager.fontManager.ttflist.extend(font_list)

mpl.rcParams['font.family'] = 'My Custom Font'

The fontpaths kwarg can also be a string in case you only have a single directory to import from.

Seanny123
  • 8,776
  • 13
  • 68
  • 124
Geotob
  • 2,847
  • 1
  • 16
  • 26
  • 5
    It helped a lot! I also ran this to check exactly what name to use for 'my custom font' `[f.name for f in matplotlib.font_manager.fontManager.ttflist]` from this [post](https://stackoverflow.com/questions/21461155/change-matplotlibs-default-font) – esperluette Oct 13 '17 at 14:43
20

2021 Update

I came across this issue recently and found this the most simple way to deal with it.

Adding the font is the important part, otherwise, the font will not be detected:

import matplotlib.pyplot as plt
from matplotlib import font_manager

font_path = 'Inter-Regular.otf'  # Your font path goes here
font_manager.fontManager.addfont(font_path)
prop = font_manager.FontProperties(fname=font_path)

plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = prop.get_name()

Note that this requires matplotlib>=3.2. For older versions, the addfont method doesn't exist and the above will fail with AttributeError: 'FontManager' object has no attribute 'addfont'

Mayou36
  • 4,613
  • 2
  • 17
  • 20
gitnoob
  • 211
  • 2
  • 5
  • 1
    I'm inserting your snippet into a script but the system is complaining with: font_manager.fontManager.addfont(font_dir) && AttributeError: 'FontManager' object has no attribute 'addfont' – afernandezody Apr 11 '22 at 20:06
  • This works for the latest Matplotlib (3.5.1). Did you try to check your matplotlib version and uninstall any outdated ones? – gitnoob Apr 12 '22 at 21:17
  • Yes, it actually worked once I moved to v3. Thanks! – afernandezody Apr 13 '22 at 23:06
8

For newer matplotlib module (e.g. version >=3.2)
createFontList is deprecated.

Hoever, you can make a font entry with ttf file path and custom name,
then add it to fontManager.ttflist, and assign matplotlib.rcParams['font.familt'] to that name.
Now you can start to make a plot without 'fontproperties' etc.

import matplotlib as mpl
import matplotlib.font_manager as fm

fe = fm.FontEntry(
    fname='your custom ttf file path',
    name='your custom ttf font name')
fm.fontManager.ttflist.insert(0, fe) # or append is fine
mpl.rcParams['font.family'] = fe.name # = 'your custom ttf font name'
SCKU
  • 783
  • 9
  • 14