# Matplotlib figures with Helvetica labels – helvet vs. tgheros

I recently spent a frustrating amount of time figuring out a good way to have labels and text in the Helvetica font in Matplotlib. Here’s what I found:

The figure

is generated by the following code:

import pylab as pl
import numpy as np

from matplotlib import rc

rc('text', usetex=True)
pl.rcParams['text.latex.preamble'] = [
r'\usepackage{tgheros}',    # helvetica font
r'\usepackage{sansmath}',   # math-font matching  helvetica
r'\sansmath'                # actually tell tex to use it!
r'\usepackage{siunitx}',    # micro symbols
r'\sisetup{detect-all}',    # force siunitx to use the fonts
]

pl.figure(1, figsize=(6,4))
ax = pl.axes([0.1, 0.1, 0.8, 0.7])
t = np.arange(0.0, 1.0+0.01, 0.01)
s = np.cos(2*2*np.pi*t)+2
pl.plot(t, s)

pl.xlabel(r'time $\lambda$')
pl.ylabel(r'\textit{voltage (mV)}',fontsize=16)
pl.title(r'\TeX\ Number 1234567890 anisotropic ' +
r'$\displaystyle\sum_{n=1}^\infty' + r'\frac{-e^{i\pi}}{2^n}$' +
r' and \SI{3}{\micro\metre}',fontsize=16, color='r')

pl.grid(True)
pl.savefig('matplotlib_helvetica.pdf')


To achieve the consistent Helvetica font in the figure the LaTeX rendering of Matplotlib labels and text is used. This setup is adapted from an StackExchange answer by Paul H.

Most importantly, I use the tgheros instead of the helvet package. You can see the difference in the images below:

The bottom rendering of helvet has some baseline alignment problems, the “i” is positively floating in the air and the jump between “t” and “r” is particularly noticeable.

The sansmath package is the correct math-font matching Helvetica, as pointed out here.

Finally, siunitx is used for the correct display of measurements in SI units. Here, for example, 3 micrometres are rendered in the title – don’t make the mistake of putting the siuntix expression in a math environment, then the fonts won’t work!