27

The font of the axis tick mark labels produced from the following code isn't Helvetica, but is still the default serif Computer Modern. Any suggestions are greatly appreciated.

from matplotlib import rc, font_manager
from numpy import arange, cos, pi
from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \
grid, savefig, show

sizeOfFont = 12
fontProperties = {'family':'sans-serif','sans-serif':['Helvetica'],
    'weight' : 'normal', 'size' : sizeOfFont}
ticks_font = font_manager.FontProperties(family='Helvetica', style='normal',
    size=sizeOfFont, weight='normal', stretch='normal')
rc('text', usetex=True)
rc('font',**fontProperties)
figure(1, figsize=(6,4))
ax = axes([0.1, 0.1, 0.8, 0.7])
t = arange(0.0, 1.0+0.01, 0.01)
s = cos(2*2*pi*t)+2
plot(t, s)

for label in ax.get_xticklabels():
    label.set_fontproperties(ticks_font)

for label in ax.get_yticklabels():
    label.set_fontproperties(ticks_font)

xlabel(r'\textbf{time (s)}')
ylabel(r'\textit{voltage (mV)}',fontsize=16,family='Helvetica')
title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!",
    fontsize=16, color='r')
grid(True)
savefig('tex_demo.pdf')

show()
Rob
  • 273
  • 1
  • 3
  • 4
  • Are you sure you have installed Helvetica font correctly? I think on my laptop the font showing up is sans-serif Helvetica... – Taro Sato Sep 07 '12 at 17:34
  • I assume that its installed correctly because the axis labels are in Helvetica. In the example, the equation and the tick labels are Computer Modern, but everything else is Helvetica. – Rob Sep 07 '12 at 18:18
  • Okay, thanks. I misunderstood what you were asking... – Taro Sato Sep 07 '12 at 18:22
  • Are the tick labels Helvetica on your machine? – Rob Sep 07 '12 at 18:28

3 Answers3

22

I think the confusion here stems from the fact that you're mixing TeX and non-TeX font commands.

This turns on TeX mode, so all of the text is rendered with an external TeX installation:

rc('text', usetex=True)

In this line, setting it to sans-serif will get passed along to TeX, but a specific ttf font name can not be used by TeX, so the second part (involving Helvetica) is ignored. And setting the default body text in TeX does not (by default) change the math font. This is (unfortunately standard TeX behavior).

rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})

This affects the font set used by matplotlib's internal mathtext renderer, and has no effect on TeX:

rc('mathtext', fontset='stixsans')

The solution I use when I want all sans-serif out of TeX is to use the cmbright package, which can be turned on by adding:

rc('text.latex', preamble=r'\usepackage{cmbright}')

That may require installing the cmbright LaTeX package if you don't already have it.

mdboom
  • 271
  • 2
  • 4
21

Okay, this worked for me. Replace the following lines:

for label in ax.get_xticklabels():
    label.set_fontproperties(ticks_font)

for label in ax.get_yticklabels():
    label.set_fontproperties(ticks_font)

with this:

from matplotlib.pyplot import gca
a = gca()
a.set_xticklabels(a.get_xticks(), fontProperties)
a.set_yticklabels(a.get_yticks(), fontProperties)

What you did in your original code makes sense to me, but I get different results this way. Weird.

Taro Sato
  • 1,444
  • 1
  • 15
  • 19
  • 1
    No error, but doesn't work either. Is there anything you have to define before or after this? Anything that might overwrite this setting? – imrek Aug 22 '15 at 14:20
  • @DrunkenMaster the code still works for me. What wasn't clear in my original answer was that the function `gca` needed to be imported explicitly because the original code in the question did not do so. – Taro Sato Aug 22 '15 at 19:24
  • This unfortunately changes the power notation to scalar notation in log axes, and it is unclear to me how it can be restored while still maintaining the tick font. Any ideas? – delete000 May 09 '18 at 17:41
  • It's been a while since this answer was written, but for log axes, this might be a better starting point: https://stackoverflow.com/a/21920673/515392. If you get a handle to an axis object, it may have a way to set font properties with that object. – Taro Sato May 09 '18 at 22:55
13

I just found a little simple way you can try. Just call the .xticks method and give the fontname as user-set argument.

e.g.

import matplotlib.pyplot as plt
plt.figure()
#... do the plot you want...
plt.yticks(fontname = "Times New Roman")  # This argument will change the font.
plt.show()
CEKim
  • 149
  • 1
  • 3