5

In matplotlib.pyplot I frequently need to change the font size for 4 different text elements within a given axes:

  • axis labels
  • major tick labels
  • legend text
  • axes title

This is how I currently do it:

import matplotlib.pyplot as plt
plt.plot([1,2,3], label = 'Whatever')
plt.xlabel('xaxis', fontsize = 16)
plt.ylabel('yaxis', fontsize = 20)
plt.legend(fontsize = 18)
plt.xticks(fontsize = 20)
plt.yticks(fontsize = 20)
plt.title('PLOT', fontsize = 20)

As you can see that is quite a few lines of code, especially considering usually I need for these all to be the same font size (though this is not reflected in this example). Also these lines can be scattered throughout my script and difficult to find if I need to reset the font. I tend to think of the formatting elements like grid, font, color and legend as separate from the actual data processing/plotting. I therefore have two questions:

  • Is there a way to use pyplot to get all these elements then set their fontsize all in one go?
  • Is there a way to set the fontsize of these objects (especially the x and y labels and the title, though preferably all) after plotting ?
user32882
  • 5,094
  • 5
  • 43
  • 82

1 Answers1

6

There are actually multiple ways to set font-sizes in matplotlib. The most convenient is to set the global font.size parameter in the matplotlibrc/in the global matplotlib rcParams which is generally a nice way to set your layout because it will then be the same for all plots. This will change all elements' font sizes (though only of those that are created after the change). All font sizes are set relative to this font size if they are not given explicitly. As far as I know, only titles will be larger though, while the rest of the elements will actually have the set font size. This would easily and conveniently solve your first problem. (A slightly less convenient solution to both your problems is shown at the bottom of this answer.)

Default:

import matplotlib as mpl
import matplotlib.pyplot as plt

plt.plot([1,2,3], label = 'Whatever')
plt.xlabel('xaxis')
plt.ylabel('yaxis')
plt.legend()
plt.xticks()
plt.yticks()
plt.title('PLOT')
plt.show()

gives:

enter image description here

Changing the font size gives:

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.size"] = 18

plt.plot([1,2,3], label = 'Whatever')
plt.xlabel('xaxis')
plt.ylabel('yaxis')
plt.legend()
plt.xticks()
plt.yticks()
plt.title('PLOT')
plt.gcf().set_tight_layout(True) # To prevent the xlabel being cut off
plt.show()

then gives:

enter image description here

Changing the size after plotting does not work though:

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.size"] = 7

plt.plot([1,2,3], label = 'Whatever')
plt.xlabel('xaxis')
plt.ylabel('yaxis')
plt.legend()
plt.xticks()
plt.yticks()
plt.title('PLOT')

mpl.rcParams["font.size"] = 18

plt.show()

gives:

enter image description here

Changing the font size after plotting sadly is less convenient. You can do it nonetheless. This answer shows a rather nice way of doing it:

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.size"] = 7

plt.plot([1,2,3], label = 'Whatever')
plt.xlabel('xaxis')
plt.ylabel('yaxis')
plt.legend()
plt.xticks()
plt.yticks()
plt.title('PLOT')

ax = plt.gca()
ax.title.set_fontsize(20)
for item in ([ax.xaxis.label, ax.yaxis.label] +
              ax.get_xticklabels() + ax.get_yticklabels() + 
              ax.get_legend().get_texts()):
     item.set_fontsize(18)

plt.gcf().set_tight_layout(True)
plt.show()

gives:

enter image description here

If you want to have it in one line, you could define a function that you pass the axis object similar to this:

def changeFontSize(ax, size):
    ax.title.set_fontsize(size)
    for item in ([ax.xaxis.label, ax.yaxis.label] +
                  ax.get_xticklabels() + ax.get_yticklabels() + 
                  ax.get_legend().get_texts()):
         item.set_fontsize(size)

changeFontSize(plt.gca())
jotasi
  • 5,077
  • 2
  • 29
  • 51