How to use a (random) *.otf or *.ttf font in matplotlib?
See the example here: http://matplotlib.sourceforge.net/examples/api/font_file.html
In general, you'd do something like this if you're wanting to use a specific .ttf
file. (Keep in mind that pointing to a specific font file is usually a bad idea!)
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(range(10))
prop = fm.FontProperties(fname='/usr/share/fonts/truetype/groovygh.ttf')
ax.set_title('This is some random font', fontproperties=prop, size=32)
plt.show()
Usually, you'd just point to the name of the font, and let matplotlib worry about finding the specific file. E.g.
import matplotlib.pyplot as plt
plt.plot(range(10))
plt.title('This is some random font', family='GroovyGhosties', size=32)
plt.show()
If you want to have matplotlib always use a particular font, then customize your .matplotlibrc
file. (font.family
is what you'd want to set. Note that you should specify the name of the font, not the path to a specific .ttf file.)
As an example of doing this dynamically (i.e. without setting up a specific .matplotlibrc
file):
import matplotlib as mpl
mpl.rcParams['font.family'] = 'GroovyGhosties'
import matplotlib.pyplot as plt
plt.plot(range(10))
plt.title('Everything is crazy!!!', size=32)
plt.show()
Font of labels in matplotlib
You can pass a fontdict with the font parameters, specifying the 'family' with the font you want to use:
font = {'family': 'Latin Modern Roman',
'color': 'darkred',
'weight': 'normal',
'size': 16,
}
plt.ylabel('label-text', fontdict=font)
or set the family in the label:
plt.ylabel('label-text', family='Latin Modern Roman')
There's a full example in the docs using fontdict
Set matplotlib font by family name when there are multiple fonts with same name
That is a really good question. I will provide the way I found the solution to that specific problem. In order to reproduce it we first have to download the given fonts from here (I downloaded the version 10 regular and the 17 version regular to see a clearer difference). Once installed we can check if our new font is found by matplotlib
:
from matplotlib import font_manager
font_manager.font_manager.findSystemFonts(fontext='otf') # Matplotlib associates with
# the .otf extension two more extensions viz. '.ttc' and '.ttf', as can be obtain over
# font_manager.get_fontext_synonyms('otf')
Once you have found your specified path to your .otf
file, we can use the font_manager
to make that specific version our selected font.
# This will create an object which contains your file and give it a custom name
# Here is the idea of this: https://stackoverflow.com/questions/35668219/how-to-set-up-a-custom-font-with-custom-path-to-matplotlib-global-font
fe = font_manager.FontEntry(
fname='C:\\Users\\<your_user_name>\\AppData\\Local\\Microsoft\\Windows\\Fonts\\latin-modern-roman.mroman10-regular.otf',
name='10erLatin')
font_manager.fontManager.ttflist.insert(0, fe)
mpl.rcParams['font.family'] = fe.name
Lets plot it so that we can later see whether it worked or not.
import numpy as np
from pathlib import Path
import matplotlib as mpl
# import PyQt5
# mpl.use('Qt5Agg') # I want to plot it inline ;)
import matplotlib.pyplot as plt
mpl.rcParams['font.family'] = fe.name
mpl.rcParams['font.weight'] = '400'
mpl.rcParams['font.style'] = 'normal'
mpl.rcParams['font.variant'] = 'normal'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.default'] = 'it'
mpl.rcParams['mathtext.rm'] = fe.name + ':normal'
mpl.rcParams['mathtext.it'] = fe.name + ':italic'
mpl.rcParams['mathtext.bf'] = fe.name + ':bold'
mpl.rcParams['xtick.labelsize'] = 8
mpl.rcParams['ytick.labelsize'] = 8
mpl.rcParams['axes.titlesize'] = 10
mpl.rcParams['axes.labelsize'] = 10
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
fig1 = plt.figure(figsize=(3, 3*(9/16)), dpi=300)
ax1 = fig1.gca()
ax1.plot(x, y, c='r', linewidth=1.0, zorder=20)
ax1.set_xlabel(r'$x\ label$')
ax1.set_ylabel(r'$y\ label$')
fig1.tight_layout(pad=0.15)
plt.show()
Lets change it up to the 17 version of the regular font.
fe = font_manager.FontEntry(
fname='C:\\Users\\<your_user_name>\\AppData\\Local\\Microsoft\\Windows\\Fonts\\latin-modern-roman.mroman17-regular.otf',
name='17erLatin')
font_manager.fontManager.ttflist.insert(0, fe)
mpl.rcParams['font.family'] = fe.name
Again, lets plot it (used the exact same code as above to create that plot, just executed the given code beforehand).
If my hindsight is not too bad, then the text changed globally. There are some other functions which might be useful to look at, however, they are really hidden in the source code. Please let me know, if you run into problems.
Matplotlib how to set legend's font type
Pass the FontProperties object (such as font
below) to ax.legend
via the prop
parameter:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.font_manager as font_manager
fig, ax = plt.subplots()
x = np.linspace(-10, 10, 100)
ax.plot(np.sin(x)/x, label='Mexican hat')
font = font_manager.FontProperties(family='Comic Sans MS',
weight='bold',
style='normal', size=16)
ax.legend(prop=font)
plt.show()
On Ubuntu, you can make new fonts available to your system by running
fc-cache -f -v /path/to/fonts/directory
I'm not sure how it is done on other OSes, or how universal fc-cache
is on other flavors of Unix.
Once you've installed your font(s) so that your OS knows about them, you can cause matplotlib to regenerate its fontList by deleting the files in ~/.cache/fontconfig
and ~/.cache/matplotlib
.
The ~/.cache/matplotlib/fontList.json
file gives you a humanly-readable list of all the fonts matplotlib knows about. There, you'll find entries that look like this:
{
"weight": "bold",
"stretch": "normal",
"fname": "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf",
"_class": "FontEntry",
"name": "Comic Sans MS",
"style": "normal",
"size": "scalable",
"variant": "normal"
},
Notice that the fname
is the path to the underlying ttf file, and that there is a name
property as well. You can specify the FontProperties object by the path to the ttf file:
font = font_manager.FontProperties(fname="/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf")
or by name:
font = font_manager.FontProperties(family='Comic Sans MS',
weight='bold',
style='normal', size=16)
If you do not wish to install your font system-wide, you can specify the FontProperties
object by fname
path, thus by-passing the need to call fc-cache
and messing with ~/.cache
.
plt.show() can find font, but plt.savefig() cannot
I found this explanation this morning, which helps matplotlib find a family of fonts installed in the user profile. It's important to note that both ~/.matplotlib/fontList.py3k.cache
AND ~/.matplotlip/tex.cache
need to be cleared. I had only cleared ~/.matplotlib/fontList.py3k.cache
during my initial tries.
I still haven't identified WHY plt.show()
and plt.savefig()
behaved differently when only one cache was cleared, but I am now able to save figures with the fonts that I want.
Matplotlib: set family of text
Solved it: text.usetex has to be false:
rc('text', usetex=False)
Matplotlib font families: using Arno Pro or other fonts
One can find all of the available fonts using the font manager:
import matplotlib.font_manager
print matplotlib.font_manager.findSystemFonts(fontpaths=None)
This will print a list of all fonts available, I couldn't find Arno Pro, but maybe is you can find a .ttf
file for it (or something similar) then doing something like the following
import matplotlib.pylab as plt
plt.rcParams['font.family']='Sawasdee'
mpl.pylab.plot(range(10), mpl.pylab.sin(range(10)))
mpl.pylab.xlabel("Some crazy font", size=20)
produces:
Note I simplify picked a random file from the font manager output called Sawasdee
so this may not be installed on your computer and will throw an error.
Obviously this font is also producing some errors so you'll have to watch out for those, good luck!
Related Topics
Unicodedecodeerror: 'Ascii' Codec Can't Decode Byte 0Xe2 in Position 13: Ordinal Not in Range(128)
How to Re Import an Updated Package While in Python Interpreter
Error Running Basic Tensorflow Example
Delete File from Zipfile with the Zipfile Module
Python "Extend" for a Dictionary
How to Concatenate Two Dataframes Without Duplicates
What Is the Point of Setlevel in a Python Logging Handler
Naming Returned Columns in Pandas Aggregate Function
Get Timezone from City in Python/Django
Print Current Call Stack from a Method in Code
Regular Expression Usage in Glob.Glob
How to Extract Frequency Associated with Fft Values in Python
Reading Dynamically Generated Web Pages Using Python
How to Perform Two-Dimensional Interpolation Using Scipy
How to Call Python Functions Dynamically
High Performance Fuzzy String Comparison in Python, Use Levenshtein or Difflib