How to change the font size on a matplotlib plot

1,460,532

Solution 1

From the matplotlib documentation,

font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 22}

matplotlib.rc('font', **font)

This sets the font of all items to the font specified by the kwargs object, font.

Alternatively, you could also use the rcParams update method as suggested in this answer:

matplotlib.rcParams.update({'font.size': 22})

or

import matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 22})

You can find a full list of available properties on the Customizing matplotlib page.

Solution 2

If you are a control freak like me, you may want to explicitly set all your font sizes:

import matplotlib.pyplot as plt

SMALL_SIZE = 8
MEDIUM_SIZE = 10
BIGGER_SIZE = 12

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE)    # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title

Note that you can also set the sizes calling the rc method on matplotlib:

import matplotlib

SMALL_SIZE = 8
matplotlib.rc('font', size=SMALL_SIZE)
matplotlib.rc('axes', titlesize=SMALL_SIZE)

# and so on ...

Solution 3

If you want to change the fontsize for just a specific plot that has already been created, try this:

import matplotlib.pyplot as plt

ax = plt.subplot(111, xlabel='x', ylabel='y', title='title')
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
             ax.get_xticklabels() + ax.get_yticklabels()):
    item.set_fontsize(20)

Solution 4

matplotlib.rcParams.update({'font.size': 22})

Solution 5

Update: See the bottom of the answer for a slightly better way of doing it.
Update #2: I've figured out changing legend title fonts too.
Update #3: There is a bug in Matplotlib 2.0.0 that's causing tick labels for logarithmic axes to revert to the default font. Should be fixed in 2.0.1 but I've included the workaround in the 2nd part of the answer.

This answer is for anyone trying to change all the fonts, including for the legend, and for anyone trying to use different fonts and sizes for each thing. It does not use rc (which doesn't seem to work for me). It is rather cumbersome but I could not get to grips with any other method personally. It basically combines ryggyr's answer here with other answers on SO.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager

# Set the font dictionaries (for plot title and axis titles)
title_font = {'fontname':'Arial', 'size':'16', 'color':'black', 'weight':'normal',
              'verticalalignment':'bottom'} # Bottom vertical alignment for more space
axis_font = {'fontname':'Arial', 'size':'14'}

# Set the font properties (for use in legend)   
font_path = 'C:\Windows\Fonts\Arial.ttf'
font_prop = font_manager.FontProperties(fname=font_path, size=14)

ax = plt.subplot() # Defines ax variable by creating an empty plot

# Set the tick labels font
for label in (ax.get_xticklabels() + ax.get_yticklabels()):
    label.set_fontname('Arial')
    label.set_fontsize(13)

x = np.linspace(0, 10)
y = x + np.random.normal(x) # Just simulates some data

plt.plot(x, y, 'b+', label='Data points')
plt.xlabel("x axis", **axis_font)
plt.ylabel("y axis", **axis_font)
plt.title("Misc graph", **title_font)
plt.legend(loc='lower right', prop=font_prop, numpoints=1)
plt.text(0, 0, "Misc text", **title_font)
plt.show()

The benefit of this method is that, by having several font dictionaries, you can choose different fonts/sizes/weights/colours for the various titles, choose the font for the tick labels, and choose the font for the legend, all independently.


UPDATE:

I have worked out a slightly different, less cluttered approach that does away with font dictionaries, and allows any font on your system, even .otf fonts. To have separate fonts for each thing, just write more font_path and font_prop like variables.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.ticker
# Workaround for Matplotlib 2.0.0 log axes bug https://github.com/matplotlib/matplotlib/issues/8017 :
matplotlib.ticker._mathdefault = lambda x: '\\mathdefault{%s}'%x 

# Set the font properties (can use more variables for more fonts)
font_path = 'C:\Windows\Fonts\AGaramondPro-Regular.otf'
font_prop = font_manager.FontProperties(fname=font_path, size=14)

ax = plt.subplot() # Defines ax variable by creating an empty plot

# Define the data to be plotted
x = np.linspace(0, 10)
y = x + np.random.normal(x)
plt.plot(x, y, 'b+', label='Data points')

for label in (ax.get_xticklabels() + ax.get_yticklabels()):
    label.set_fontproperties(font_prop)
    label.set_fontsize(13) # Size here overrides font_prop

plt.title("Exponentially decaying oscillations", fontproperties=font_prop,
          size=16, verticalalignment='bottom') # Size here overrides font_prop
plt.xlabel("Time", fontproperties=font_prop)
plt.ylabel("Amplitude", fontproperties=font_prop)
plt.text(0, 0, "Misc text", fontproperties=font_prop)

lgd = plt.legend(loc='lower right', prop=font_prop) # NB different 'prop' argument for legend
lgd.set_title("Legend", prop=font_prop)

plt.show()

Hopefully this is a comprehensive answer

Share:
1,460,532
Herman Schaaf
Author by

Herman Schaaf

Software engineer (Go, Python, JavaScript, Java, C++) currently working on data pipeline and machine learning applications at Skyscanner. hermanschaaf.com

Updated on December 16, 2020

Comments

  • Herman Schaaf
    Herman Schaaf over 3 years

    How does one change the font size for all elements (ticks, labels, title) on a matplotlib plot?

    I know how to change the tick label sizes, this is done with:

    import matplotlib 
    matplotlib.rc('xtick', labelsize=20) 
    matplotlib.rc('ytick', labelsize=20) 
    

    But how does one change the rest?

  • yota
    yota almost 10 years
    nice, except it override any fontsize property found on it's way è_é
  • haccks
    haccks about 9 years
    Where can I find more options for elements like 'family', 'weight', etc.?
  • Herman Schaaf
    Herman Schaaf about 9 years
    @haccks I added a link to the customizing matplotlib page in the answer.
  • haccks
    haccks about 9 years
    @HermanSchaaf; I visited that page before. I would like to know all the options for 'family' Like 'normal', 'sans-serif', etc.
  • LondonRob
    LondonRob almost 9 years
    Since many people start with import matplotlib.pyplot as plt, you might like to point out that pyplot has rc as well. You can do plt.rc(... without having to change your imports.
  • Ébe Isaac
    Ébe Isaac over 7 years
    My purpose was to have the font of x-y labels, ticks and the titles to be of different sizes. A modified version of this worked so well for me.
  • user32882
    user32882 almost 7 years
    Does this permanently mess up the maplotlib defaults for fontsize??
  • James S.
    James S. almost 7 years
    To get the legends as well use ax.legend().get_texts(). Tested on Matplotlib 1.4.
  • fviktor
    fviktor almost 7 years
    I tried many of the answers. This one looks the best, at least in Jupyter notebooks. Just copy the above block at the top and customize the three font size constants.
  • FvD
    FvD over 6 years
    For the impatient: The default font size is 10, as in the second link.
  • SeF
    SeF over 6 years
    Agree with fvitkor, that's the best answer!
  • Fernando Irarrázaval G
    Fernando Irarrázaval G about 6 years
    For me the title size didn't work. I used: plt.rc('axes', titlesize=BIGGER_SIZE)
  • jimh
    jimh about 6 years
    This answers the question most directly. Thank you.
  • Josiah Yoder
    Josiah Yoder almost 6 years
    @LondonRob plt.rcParams.update({'font.size':22}) works, too. Thanks.
  • DannyMoshe
    DannyMoshe almost 6 years
    @haccks for all options run plt.rcParams.keys()
  • DannyMoshe
    DannyMoshe almost 6 years
    I believe 'weight' is no longer valid and is now 'font.weight'
  • BallpointBen
    BallpointBen almost 6 years
    I think you can combine all settings for the same object into one line. E.g., plt.rc('axes', titlesize=SMALL_SIZE, labelsize=MEDIUM_SIZE)
  • Paw
    Paw over 5 years
    To avoid the axis label being cut-off, save figure with the bbox_inches argument fig.savefig('Basic.png', bbox_inches="tight")
  • sepehr
    sepehr over 5 years
    Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
  • dylnan
    dylnan over 5 years
    Might need an ax=plt.gca() if the plot was created without defining an axis.
  • Terry Brown
    Terry Brown over 5 years
    @user32882 - not permanently, it's not saved to disk, but I would assume it would change subsequent plots generated in the same code unless the original value is stored and restored, which is no always convenient. You can do something like for label in (ax.get_xticklabels() + ax.get_yticklabels()): label.set_fontsize(22) to affect text size in a single figure.
  • Zythyr
    Zythyr over 4 years
    What if I am NOT saving the figure? I am plotting in Juypter Notebook and the resulting axis labels get cut-off.
  • ybull
    ybull over 4 years
    Thanks! Pointing out the dpi settings was extremely helpful to me in preparing printable versions of my plots without having to adjust all the line sizes, font sizes, etc.
  • Guimoute
    Guimoute over 4 years
    @JamesS. Rather use ax.get_legend().get_texts(), because ax.legend() redraws the whole legend with default parameters on top of returning the value of ax.get_legend().
  • Songio
    Songio over 4 years
    In may case this solution works only if I create a first plot, then "update" as suggested, which leads to updated font size for new figures. Maybe the first plot is necessary to initialize rcParams...
  • Charlie G
    Charlie G over 4 years
    If you want to temporarily change the font size, plt.style.context will accept a dictionary of rcParams like so: with plt.style.context({'font.size': 22}):
  • Ramon Crehuet
    Ramon Crehuet almost 4 years
    To prevent the label cut-off, also in the notebook as @Zythyr asks, you can use plt.tight_layout()
  • JiK
    JiK almost 4 years
    Doesn't this just change the tick font size?
  • dnalow
    dnalow almost 4 years
    @Zythyr You can use the dpi=XXX argument also in the call of plt.figure(): plt.figure(figsize=(4,3), dpi=300) to achieve the same result without saving
  • PatrickT
    PatrickT over 2 years
    Or using matplotlib's styling, which is very similar to your idea: matplotlib.org/stable/tutorials/introductory/customizing.htm‌​l
  • LunkRat
    LunkRat about 2 years
    I am grateful that you posted this answer here! It addressed the root problem that my 'font size' increase was attempting to solve.