1
votes

I am using Python 2.7, Matplotlib 1.5.1, and attempting to use LaTeX for all text rendering. I am trying to make the font of Plot 1's axis tick labels match those in Plot 2. For some reason, since I did not explicitly set the tick labels in Plot 1, they remain in the default LaTeX font. I would like all tick labels, regardless of whether they were explicitly set, to match the font of those in Plot 2. While knowing how to change both sets of tick label fonts to some 3rd, consistent font would be useful, I am more interested in knowing how to set Plot 1's tick fonts to be the exact font shown in Plot 2 below.

Also, since I imagine it might be a more common query from someone in the same situation, it would be good to know how to set both sets of tick labels to match those in Plot 1.

from matplotlib import pyplot as plt
plt.rc('text', usetex=True)

my_fig = plt.figure(figsize=(8,4))

x = range(10)
y = range(10)

ax1 = my_fig.add_subplot(1, 2, 1)
ax1.plot(x, y)
ax1.set_title('Plot 1')

ax2 = my_fig.add_subplot(1, 2, 2)
ax2.plot(x, y)
ax2.set_xticklabels(range(10))
ax2.set_yticklabels(range(10))
ax2.set_title(r'\textit{Plot 2}')

enter image description here

1
Ignore my (now deleted) comments, have this sorted. - tacaswell

1 Answers

0
votes

First, using set_yticklabels like this is dangerous because the locator is still the auto locator (automatically places ticks based on data range) but the labels come from a FixedFormatter which means the first tick is always labeled with the first position in the sequence which decouples your tick labels from your data.

from matplotlib import pyplot as plt
import matplotlib.ticker as mticker
plt.rc('text', usetex=True)

my_fig = plt.figure(figsize=(8,4))

x = range(10)
y = range(10)

ax1 = my_fig.add_subplot(1, 2, 1)
ax1.plot(x, y)
ax1.set_title('Plot 1')

ax2 = my_fig.add_subplot(1, 2, 2)
ax2.plot(x, y)
# just being very explicit about what `set_xticks` and `set_xticklabels`
# is doing
ax2.xaxis.set_major_locator(mticker.FixedLocator(range(10)))
ax2.yaxis.set_major_locator(mticker.FixedLocator(range(10)))
ax2.yaxis.set_major_formatter(mticker.FixedFormatter(range(10)))
ax2.xaxis.set_major_formatter(mticker.FixedFormatter(
    ['${}$'.format(_) for _ in range(10)]))

ax2.set_title(r'\textit{Plot 2}')

example output

Compare:

In [157]: ax2.xaxis.get_ticklabels()[1]
Out[157]: Text(1,0,'$1$')

In [158]: ax2.yaxis.get_ticklabels()[1]
Out[158]: Text(0,1,'1')

In [159]: ax1.yaxis.get_ticklabels()[1]
Out[159]: Text(0,0,'$0$')

In the case of the the right xaxis and both axes on the left, the numbers are typeset in math mode. In the case on the left, the LaTeX markup is added by the ScalarFormatter (the default formatter). If you used a FixedFormatter (which I did explicitly here, the OP code is doing implicitly via sex_xticklabels) no additional markup is added and the contents of the list of labels is just passed through to the Text instance which is used to draw the tick labels.

TL;DR

  • unless you want to typeset text do not use set_xticklabels, use set_xticks and let the default Formatter 'do the right thing'
  • do the LaTeX markup your self