I want to give my graph a title in big 18pt font, then a subtitle below it in smaller 10pt font. How can I do this in matplotlib? It appears the title() function only takes one single string with a single fontsize attribute. There has to be a way to do this, but how?
- 29,908
- 21
- 78
- 111
-
6The shortest answer to your ``subtitle`` question is: There is a built-in ``suptitle()`` function. Thus, combining ``suptitle()/title()`` is similar to the more intuitively named ``title()/subtitle()``. See Floris van Vugt's answer and Tim Misner's follow-up below. – PatrickT Apr 17 '18 at 11:50
7 Answers
What I do is use the title() function for the subtitle and the suptitle() for the main title (they can take different font size arguments). Hope that helps!
- 863
- 1
- 9
- 24
- 931
- 1
- 6
- 3
-
At least on a standard polar plot, the title, the suptitle, and the 90 degree marker all overlap, especially if you use bigger fonts. – gbronner Oct 10 '14 at 01:00
-
3One issue with this is that `title` and `suptitle` center differently, so they may not align for your plot. – Alex Nov 22 '19 at 23:19
-
-
For an actual example of this, see [this other answer here](https://stackoverflow.com/a/54842869/4561887). – Gabriel Staples Jun 28 '21 at 18:06
Although this doesn't give you the flexibility associated with multiple font sizes, adding a newline character to your pyplot.title() string can be a simple solution;
plt.title('Really Important Plot\nThis is why it is important')
- 1,237
- 1
- 12
- 11
-
7Most of the time you want some stylistic differences between titles and subtitles. Otherwise it just looks like a sloppy title split over two lines. – AnnanFay Jun 08 '17 at 01:49
-
This is a pandas code example that implements Floris van Vugt's answer (Dec 20, 2010). He said:
>What I do is use the title() function for the subtitle and the suptitle() for the >main title (they can take different fontsize arguments). Hope that helps!
import pandas as pd
import matplotlib.pyplot as plt
d = {'series a' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
'series b' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
title_string = "This is the title"
subtitle_string = "This is the subtitle"
plt.figure()
df.plot(kind='bar')
plt.suptitle(title_string, y=1.05, fontsize=18)
plt.title(subtitle_string, fontsize=10)
Note: I could not comment on that answer because I'm new to stackoverflow.
- 313
- 3
- 5
-
4What if you have two subplots? If I call `subtitle_string=('Upper panel: Max, Avg, Min, Footprint % | Lower panel: Footprint % and Critical Cells %')` and then `plt.suptitle(title_string, y=0.99, fontsize=17)` in a chart with two subplots, the subtitle gets printed above the second subplot instead of the first and I don't see the legend printed. – FaCoffee Nov 13 '15 at 12:11
I don't think there is anything built-in, but you can do it by leaving more space above your axes and using figtext:
axes([.1,.1,.8,.7])
figtext(.5,.9,'Foo Bar', fontsize=18, ha='center')
figtext(.5,.85,'Lorem ipsum dolor sit amet, consectetur adipiscing elit',fontsize=10,ha='center')
ha is short for horizontalalignment.
- 40,105
- 5
- 71
- 99
-
It is not clear from the answer, which `axes` is being called. The provenience of `figtext` can also only be found out by following the link. Additionally, the answer might be outdated. Would it be possible to update the answer to a more recent version of Matplotlib? – Stefan_EOX Feb 21 '22 at 11:24
The solution that worked for me is:
- use
suptitle()for the actual title - use
title()for the subtitle and adjust it using the optional parametery:
import matplotlib.pyplot as plt
"""
some code here
"""
plt.title('My subtitle',fontsize=16)
plt.suptitle('My title',fontsize=24, y=1)
plt.show()
There can be some nasty overlap between the two pieces of text. You can fix this by fiddling with the value of y until you get it right.
- 436
- 5
- 8
-
The example currently shows suptitle using the `y` parameter, not title as in the explanation text ... – sdbbs Nov 18 '20 at 13:13
Just use TeX ! This works :
title(r"""\Huge{Big title !} \newline \tiny{Small subtitle !}""")
EDIT: To enable TeX processing, you need to add the "usetex = True" line to matplotlib parameters:
fig_size = [12.,7.5]
params = {'axes.labelsize': 8,
'text.fontsize': 6,
'legend.fontsize': 7,
'xtick.labelsize': 6,
'ytick.labelsize': 6,
'text.usetex': True, # <-- There
'figure.figsize': fig_size,
}
rcParams.update(params)
I guess you also need a working TeX distribution on your computer. All details are given at this page:
- 690
- 6
- 13
-
sounds interesting, but do you have set any additional flags for matplotlib to enable tex mode? Using 1.4.1 with default settings does not work for your example. Plotting math with r"$ expr $" in title works by the way. – marscher Nov 28 '14 at 16:26
As mentioned here, uou can use matplotlib.pyplot.text objects in order to achieve the same result:
plt.text(x=0.5, y=0.94, s="My title 1", fontsize=18, ha="center", transform=fig.transFigure)
plt.text(x=0.5, y=0.88, s= "My title 2 in different size", fontsize=12, ha="center", transform=fig.transFigure)
plt.subplots_adjust(top=0.8, wspace=0.3)
- 3,566
- 5
- 25
- 43