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?
15 Answers
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.
12If 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 ... 4If 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) 5matplotlib.rcParams.update({'font.size': 22}) 1Update: 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 : 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
Here is a totally different approach that works surprisingly well to change the font sizes:
Change the figure size!
I usually use code like this:
import matplotlib.pyplot as plt import numpy as np fig = plt.figure(figsize=(4,3)) ax = fig.add_subplot(111) x = np.linspace(0,6.28,21) ax.plot(x, np.sin(x), '-^', label="1 Hz") ax.set_title("Oscillator Output") ax.set_xlabel("Time (s)") ax.set_ylabel("Output (V)") ax.grid(True) ax.legend(loc=1) fig.savefig('Basic.png', dpi=300) The smaller you make the figure size, the larger the font is relative to the plot. This also upscales the markers. Note I also set the dpi or dot per inch. I learned this from a posting the AMTA (American Modeling Teacher of America) forum. Example from above code: 
You can use plt.rcParams["font.size"] for setting font_size in matplotlib and also you can use plt.rcParams["font.family"] for setting font_family in matplotlib. Try this example:
import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') label = [1,2,3,4,5,6,7,8] x = [0.001906,0.000571308,0.0020305,0.0037422,0.0047095,0.000846667,0.000819,0.000907] y = [0.2943301,0.047778308,0.048003167,0.1770876,0.532489833,0.024611333,0.157498667,0.0272095] plt.ylabel('eigen centrality') plt.xlabel('betweenness centrality') plt.text(0.001906, 0.2943301, '1 ', ha='right', va='center') plt.text(0.000571308, 0.047778308, '2 ', ha='right', va='center') plt.text(0.0020305, 0.048003167, '3 ', ha='right', va='center') plt.text(0.0037422, 0.1770876, '4 ', ha='right', va='center') plt.text(0.0047095, 0.532489833, '5 ', ha='right', va='center') plt.text(0.000846667, 0.024611333, '6 ', ha='right', va='center') plt.text(0.000819, 0.157498667, '7 ', ha='right', va='center') plt.text(0.000907, 0.0272095, '8 ', ha='right', va='center') plt.rcParams["font.family"] = "Times New Roman" plt.rcParams["font.size"] = "50" plt.plot(x, y, 'o', color='blue') Use plt.tick_params(labelsize=14)
Here is what I generally use in Jupyter Notebook:
# Jupyter Notebook settings from IPython.core.display import display, HTML display(HTML("<style>.container { width:95% !important; }</style>")) %autosave 0 %matplotlib inline %load_ext autoreload %autoreload 2 from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = "all" # Imports for data analysis import pandas as pd import matplotlib.pyplot as plt pd.set_option('display.max_rows', 2500) pd.set_option('display.max_columns', 500) pd.set_option('display.max_colwidth', 2000) pd.set_option('display.width', 2000) pd.set_option('display.float_format', lambda x: '%.3f' % x) #size=25 size=15 params = {'legend.fontsize': 'large', 'figure.figsize': (20,8), 'axes.labelsize': size, 'axes.titlesize': size, 'xtick.labelsize': size*0.75, 'ytick.labelsize': size*0.75, 'axes.titlepad': 25} plt.rcParams.update(params) The changes to the rcParams are very granular, most of the time all you want is just scaling all of the font sizes so they can be seen better in your figure. The figure size is a good trick but then you have to carry it for all of your figures. Another way (not purely matplotlib, or maybe overkill if you don't use seaborn) is to just set the font scale with seaborn:
sns.set_context('paper', font_scale=1.4) DISCLAIMER: I know, if you only use matplotlib then probably you don't want to install a whole module for just scaling your plots (I mean why not) or if you use seaborn, then you have more control over the options. But there's the case where you have the seaborn in your data science virtual env but not using it in this notebook. Anyway, yet another solution.
0Based on the above stuff:
import matplotlib.pyplot as plt import matplotlib.font_manager as fm fontPath = "/usr/share/fonts/abc.ttf" font = fm.FontProperties(fname=fontPath, size=10) font2 = fm.FontProperties(fname=fontPath, size=24) fig = plt.figure(figsize=(32, 24)) fig.text(0.5, 0.93, "This is my Title", horizontalalignment='center', fontproperties=font2) plot = fig.add_subplot(1, 1, 1) plot.xaxis.get_label().set_fontproperties(font) plot.yaxis.get_label().set_fontproperties(font) plot.legend(loc='upper right', prop=font) for label in (plot.get_xticklabels() + plot.get_yticklabels()): label.set_fontproperties(font) I totally agree with Prof Huster that the simplest way to proceed is to change the size of the figure, which allows keeping the default fonts. I just had to complement this with a bbox_inches option when saving the figure as a pdf because the axis labels were cut.
import matplotlib.pyplot as plt plt.figure(figsize=(4,3)) plt.savefig('Basic.pdf', bbox_inches='tight') This is an extension to Marius Retegan answer. You can make a separate JSON file with all your modifications and than load it with rcParams.update. The changes will only apply to the current script. So
import json from matplotlib import pyplot as plt, rcParams s = json.load(open("example_file.json") rcParams.update(s) and save this 'example_file.json' in the same folder.
{ "lines.linewidth": 2.0, "axes.edgecolor": "#bcbcbc", "patch.linewidth": 0.5, "legend.fancybox": true, "axes.color_cycle": [ "#348ABD", "#A60628", "#7A68A6", "#467821", "#CF4457", "#188487", "#E24A33" ], "axes.facecolor": "#eeeeee", "axes.labelsize": "large", "axes.grid": true, "patch.edgecolor": "#eeeeee", "axes.titlesize": "x-large", "svg.fonttype": "path", "examples.directory": "" } 1I just wanted to point out that both the Herman Schaaf's and Pedro M Duarte's answers work but you have to do that before instantiating subplots(), these settings will not affect already instantiated objects. I know it's not a brainer but I spent quite some time figuring out why are those answers not working for me when I was trying to use these changes after calling subplots().
For eg:
import matplotlib.pyplot as plt plt.rcParams.update({'font.size': 6,}) fig, ax = plt.subplots() #create your plot plt.show() or
SMALL_SIZE = 8 MEDIUM_SIZE = 10 BIGGER_SIZE = 12 plt.rc('font', size=SMALL_SIZE) # controls default text sizes plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels fig, ax = plt.subplots() #create your plot plt.show() It is mentioned in a comment but deserves its own answer:
Modify both figsize= and dpi= in conjunction to adjust the figure size and the scale of all text labels:
fig, ax = plt.subplots(1, 1, figsize=(8, 4), dpi=100) (or shorter:)
fig, ax = plt.subplots(figsize=(8, 4), dpi=100) It's a bit tricky:
figsizeactually controls the scale of the text relative to the plot extent (as well as the aspect ratio of the plot).dpiadjusts the size of the figure within the notebook (keeping constant the relative scale of the text and the plot aspect ratio).
