Custom fonts in Google Colaboratory matplotlib charts
Asked Answered
S

5

5

Using custom fonts in matplotlib locally involves storing the .ttfs in the matplotlib/mpl-data/fonts/ttf/ folder, then calling mpl.font_manager._rebuild(), then setting mpl.rcParams['font.sans-serif'].

Is there any way to do this in Google Colaboratory, where it doesn't seem that this ttf folder is accessible?

For example, I'd like to use the Roboto font. After installing, this would be invoked using mpl.rcParams['font.sans-serif'] = 'Roboto'.

Skirting answered 12/8, 2018 at 16:52 Comment(0)
P
8

The ttf folder is here:

/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf

So you want to download the ttf there, e.g.:

!wget https://github.com/Phonbopit/sarabun-webfont/raw/master/fonts/thsarabunnew-webfont.ttf -P /usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf

matplotlib.font_manager._rebuild()
matplotlib.rc('font', family='TH Sarabun New')

update 2019-12

_rebuild() no longer works. Here's another method which still works.

import matplotlib
import matplotlib.font_manager as fm

!wget https://github.com/Phonbopit/sarabun-webfont/raw/master/fonts/thsarabunnew-webfont.ttf
fm.fontManager.ttflist += fm.createFontList(['thsarabunnew-webfont.ttf'])
matplotlib.rc('font', family='TH Sarabun New')
Pen answered 14/8, 2018 at 15:30 Comment(6)
Thanks! Here's a colab where I show it working: colab.research.google.com/drive/…Skirting
I edited to have the full answer here. When do you need the font to also be in /usr/share/fonts/truetype/, as in your gist?Skirting
I'm not sure why I did that. I guess I tried many things till it worked and stopped there. BTW, what's the different between .rc(..) and setting rcParams? When should I use one or the other?Pen
OK cool. From matplotlib.org/users/customizing.html#matplotlib-rcparams, rcParams seems to be the default approach, but: "The matplotlib.rc() command can be used to modify multiple settings in a single group at once, using keyword arguments:"Skirting
This is no longer working: findfont: Font family ['Roboto'] not found. Falling back to DejaVu Sans. colab.research.google.com/drive/…Skirting
I got the same problem a few weeks ago. I've updated the solution.Pen
T
3

Wanted to add a full, succinct answer that currently works.

# Download fonts of choice. Here we download Open Sans variants to
# the current directory.
# It's not necessary to download to the share or matplotlib folders:
# /usr/share/fonts/truetype
# /usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf
!wget 'https://github.com/google/fonts/raw/master/apache/opensans/OpenSans-Regular.ttf'
!wget 'https://github.com/google/fonts/raw/master/apache/opensans/OpenSans-Light.ttf'
!wget 'https://github.com/google/fonts/raw/master/apache/opensans/OpenSans-SemiBold.ttf'
!wget 'https://github.com/google/fonts/raw/master/apache/opensans/OpenSans-Bold.ttf'
from matplotlib import font_manager as fm, pyplot as plt

# Pick up any fonts in the current directory.
# If you do end up downloading the fonts to /usr/share/fonts/truetype,
# change this to: fm.findSystemFonts()
font_files = fm.findSystemFonts('.')

# Go through and add each to Matplotlib's font cache.
for font_file in font_files:
    fm.fontManager.addfont(font_file)

# Use your new font on all your plots.
plt.rc('font', family='Open Sans')

Note, a few times this didn't work properly and the requested font wasn't displayed (even though no error or warning was shown). If that happens, try factory resetting your Colab runtime and running again.

Tu answered 22/1, 2021 at 7:40 Comment(0)
P
2

When matplotlib 3.2 is released, it will be easier.

# For now we must upgrade to 3.2 rc first
# !pip install -U --pre matplotlib  
import matplotlib as mpl
mpl.font_manager.fontManager.addfont('thsarabunnew-webfont.ttf')
mpl.rc('font', family='TH Sarabun New')

Pen answered 14/12, 2019 at 2:19 Comment(1)
Neat, though this still requires downloading the file. Passing the url doesn't work; I filed matplotlib#15936 to request this.Skirting
D
2

I would like to add my solutions as another reference:

  1. Change the seaborn style I would strongly recommend this approach as changing the font family can be very troublesome and inconvenient per seaborn design (many of the posts are no longer working on my end in 2022/05). So if you just want to get rid of the stupid default font in matplotlib and seaborn and is OK with Arial, go and type
%matplotlib inline
import matplotlib.style as style 
style.use('seaborn-deep')  
  1. Changing the font type (borrowed from top answers and tested myself. Restarting the runtime several times if it is not working as expected)
import matplotlib as mpl
import matplotlib.font_manager as fm
from matplotlib import font_manager as fm, pyplot as plt

!wget https://github.com/trishume/OpenTuringCompiler/blob/master/stdlib-sfml/fonts/Times%20New%20Roman.ttf
!wget https://github.com/matomo-org/travis-scripts/blob/master/fonts/Arial.ttf 

font_files = fm.findSystemFonts()

# Go through and add each to Matplotlib's font cache.
for font_file in font_files:
    fm.fontManager.addfont(font_file)

fm.fontManager.ttflist += fm.createFontList(['Times New Roman.ttf'])

# Use your new font on all your plots.
plt.rc('font', family='serif')


t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)

plt.plot(t, s)

plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.show()

Updates on 2022/06/08: Method 1 sometimes doesn't work out in Colab, but it works on the local Jupyter Notebook. It seems that explicitly installing and adding the font types is the only way if you want to customize font types on Colab.

Donte answered 23/5, 2022 at 16:9 Comment(0)
O
0

None of the answers above solved the issue for me. After trying and failing, this solved the issue. It works as of July 2024 with matplotlib 3.7.1. The program is for running in Google Colab. A notebook with the solution is here. Colab notebook

import matplotlib as mpl
import matplotlib.font_manager as fm
print(mpl.__version__)

!wget -O TimesNewRoman.ttf https://github.com/justrajdeep/fonts/raw/master/Times%20New%20Roman.ttf
font_dirs = ["/content/"]
font_files = fm.findSystemFonts(fontpaths=font_dirs, fontext='ttf')
for font_file in font_files:
    print(font_file) if 'TimesNewRoman' in font_file else None
    fm.fontManager.addfont(font_file)

Then, trying to plot using Times New Roman font

import matplotlib.pyplot as plt
plt.rcParams['font.serif'] = "Times New Roman"
plt.rcParams['font.family'] = "serif"

x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 3, 5]

plt.plot(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.title("Simple Plot")
plt.show()
Oscitancy answered 26/7, 2024 at 12:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.