138

It sounds as an easy problem but I do not find any effective solution to change the font (not the font size) in a plot made with matplotlib in python.

I found a couple of tutorials to change the default font of matplotlib by modifying some files in the folders where matplotlib stores its default font - see this blog post - but I am looking for a less radical solution since I would like to use more than one font in my plot (text, label, axis label, etc).

arrowd
  • 33,231
  • 8
  • 79
  • 110
SirC
  • 2,101
  • 4
  • 19
  • 24
  • Glad it helped :) Can you post the code that causes this error? I haven't seen this error myself but here's some links that may help you. http://matplotlib.1069221.n5.nabble.com/how-to-use-different-font-for-serif-td10084.html http://matplotlib.1069221.n5.nabble.com/Fonts-not-found-td12936.html – aidnani8 Jan 24 '14 at 23:33
  • The code which generates the problem is: `hfont = {'fontname':'Helvetica'} plt.annotate('Country ', (0.17,0.95), xytext=None, xycoords='figure fraction',size=28, color='red', horizontalalignment = 'left', **hfont)` and the error is `/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/m‌​atplotlib/font_manager.py:1236: UserWarning: findfont: Font family ['Helvetica'] not found. Falling back to Bitstream Vera Sans (prop.get_family(), self.defaultFamily[fontext]))` instead if I use as fontname Comic Sans MS as in your example, the code works. – SirC Jan 26 '14 at 17:54

6 Answers6

157

Say you want Comic Sans for the title and Helvetica for the x label.

csfont = {'fontname':'Comic Sans MS'}
hfont = {'fontname':'Helvetica'}

plt.title('title',**csfont)
plt.xlabel('xlabel', **hfont)
plt.show()
aidnani8
  • 2,057
  • 1
  • 13
  • 15
  • 1
    I tried and it works! It is exactly what I was looking for. However, for some fonts I have the following error message (not for all): `/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/font_manager.py:1236: UserWarning: findfont: Font family ['Helvetica'] not found. Falling back to Bitstream Vera Sans (prop.get_family(), self.defaultFamily[fontext]))`. How can I install Helvetica in the set of fonts known by matplotlib? – SirC Jan 24 '14 at 21:39
  • 4
    find the fontList.cache file, you can use only those listed there. Alternatively take a look here http://stackoverflow.com/questions/20206906/matplotlib-fonts-in-enthought-canopy – B.Kocis Mar 15 '15 at 00:40
  • 4
    following up on the above comment. To find your fontList.cache file, use matplotlib.get_cachedir() – C S Dec 15 '16 at 14:44
  • 1
    Thanks! Since this is just unpacking a dictionary with the `**` syntax, I tried simply doing `plt.title('title', fontname = 'monospace')` and it works as well! – Ali May 19 '21 at 16:39
91

You can also use rcParams to change the font family globally.

 import matplotlib.pyplot as plt
 plt.rcParams["font.family"] = "cursive"
 # This will change to your computer's default cursive font

The list of matplotlib's font family arguments is here.

Shaido
  • 27,497
  • 23
  • 70
  • 73
morepenguins
  • 1,187
  • 10
  • 21
39

I prefer to employ:

from matplotlib import rc
#rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
rc('font',**{'family':'serif','serif':['Times']})
rc('text', usetex=True)

The last line ensures that tick labels are also in the correct font.

guhur
  • 2,500
  • 1
  • 23
  • 33
  • 3
    Great way to change the font globally, I was looking for this. The last line is not necessary, not sure what Tex has to do with this. If you get an error because the font you want is not found by Matplotlib, check out this link: https://scentellegher.github.io/visualization/2018/05/02/custom-fonts-matplotlib.html – smcs Dec 17 '20 at 13:13
  • usetex=False works just as well. True gives runtime errors because it's looking for the latex package. – B Abali Jun 08 '23 at 19:37
12
import pylab as plb
plb.rcParams['font.size'] = 12

or

import matplotlib.pyplot as mpl
mpl.rcParams['font.size'] = 12
nagordon
  • 1,307
  • 2
  • 13
  • 16
  • 17
    incredibly enough this is exactly the command I was looking for. definitely not what OP was asking though – blue Aug 26 '16 at 20:35
  • 3
    The asker clearly said in the question that he is not looking to change the font size. – Hamza Abbad Apr 01 '21 at 17:24
8

The Helvetica font does not come included with Windows, so to use it you must download it as a .ttf file. Then you can refer matplotlib to it like this (replace "crm10.ttf" with your file):

import os
from matplotlib import font_manager as fm, rcParams
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

fpath = os.path.join(rcParams["datapath"], "fonts/ttf/cmr10.ttf")
prop = fm.FontProperties(fname=fpath)
fname = os.path.split(fpath)[1]
ax.set_title('This is a special font: {}'.format(fname), fontproperties=prop)
ax.set_xlabel('This is the default font')

plt.show()

print(fpath) will show you where you should put the .ttf.

You can see the output here: https://matplotlib.org/gallery/api/font_file.html

bPiMin
  • 81
  • 1
  • 3
  • Is there any way to set `fontproperties` globally so you don't have to specify it with every call to e.g. `set_title()`, `set_xlabel()`, etc.? – Kyle Mills Mar 07 '19 at 20:06
  • 3
    ^ To answer my own question: https://stackoverflow.com/questions/35668219 – Kyle Mills Mar 07 '19 at 20:20
2

I use

import matplotlib.pyplot as plt
plt.rcParams["font.family"] = "Arial"

to set the font of the entire plot.
If you want to use a different font e.g. for the title, you can use aidnani8's solution on top of that. Setting first the default font for the figure with the line above can come handy if you want to use the same font for several items though.

Adrian
  • 551
  • 5
  • 16