48

There's a similar question - but I can't make the solution proposed there work.

Here's an example plot with a long title:

#!/usr/bin/env python

import matplotlib
import matplotlib.pyplot
import textwrap

x = [1,2,3]
y = [4,5,6]

# initialization:
fig = matplotlib.pyplot.figure(figsize=(8.0, 5.0)) 

# lines:
fig.add_subplot(111).plot(x, y)

# title:
myTitle = "Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all."

fig.add_subplot(111).set_title("\n".join(textwrap.wrap(myTitle, 80)))

# tight:
(matplotlib.pyplot).tight_layout()

# saving:
fig.savefig("fig.png")

it gives a

 AttributeError: 'module' object has no attribute 'tight_layout'

and if I replace (matplotlib.pyplot).tight_layout() with fig.tight_layout() it gives:

 AttributeError: 'Figure' object has no attribute 'tight_layout'

So my question is - how do I fit the title to the plot?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Adobe
  • 12,967
  • 10
  • 85
  • 126

5 Answers5

110

Here's what I've finally used:

#!/usr/bin/env python3

import matplotlib
from matplotlib import pyplot as plt
from textwrap import wrap

data = range(5)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(data, data)

title = ax.set_title("\n".join(wrap("Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all.", 60)))

fig.tight_layout()
title.set_y(1.05)
fig.subplots_adjust(top=0.8)

fig.savefig("1.png")

enter image description here

Adobe
  • 12,967
  • 10
  • 85
  • 126
  • Excellent solution. A more streamlined alternative is fill("Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all.", 30). See https://docs.python.org/3/library/textwrap.html#textwrap.fill – KBurchfiel Jun 14 '23 at 18:23
17
import matplotlib.pyplot as plt

x = [1,2,3]
y = [4,5,6]

# initialization:
fig, axes = plt.subplots(figsize=(8.0, 5.0))

# title:
myTitle = "Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all."

# lines:
axes.plot(x, y)

# set title
axes.set_title(myTitle, loc='center', wrap=True)

plt.show()

enter image description here

  • The following also works
plt.figure(figsize=(8, 5))

# title:
myTitle = "Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all."

# lines:
plt.plot(x, y)

# set title
plt.title(myTitle, loc='center', wrap=True)

plt.show()

Note

  • The following way of adding an axes is deprecated
# lines:
fig.add_subplot(111).plot(x, y)

# title:
myTitle = "Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all."

fig.add_subplot(111).set_title(myTitle, loc='center', wrap=True)

MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
7

One way to do it is to simply change the font size of the title:

import pylab as plt

plt.rcParams["axes.titlesize"] = 8

myTitle = "Some really really long long long title I really really need - and just can't - just can't - make it any - simply any - shorter - at all."
plt.title(myTitle)
plt.show()

enter image description here

In the answer you linked are several other good solutions that involve adding newlines. There is even an automatic solution that resizes based off of the figure!

Community
  • 1
  • 1
Hooked
  • 84,485
  • 43
  • 192
  • 261
  • 1
    @Adobe the go-to page for customizing matplotlib is here: http://matplotlib.sourceforge.net/users/customizing.html, though it helps if you know what you are looking for already! – Hooked Apr 27 '12 at 14:20
  • This works, but it is a bad solution. In your example, the font for the title is even smaller than for the tick labels. That will make the title very hard to read in a publication or presentation. – gerrit Jan 26 '16 at 16:31
  • 5
    @gerrit The merit of the solution is up to the individual user. For some, like yourself, the ultimate goal might be an academic publication. For others, the title may be used to store meta-data, e.g. system parameters, thus the aesthetics are less important. It certainly is an answer to the question, "how do I fit the title to the plot". – Hooked Jan 26 '16 at 18:40
2

I preferred to adapt @Adobe's solution in this way:

plt.title("First Title\n%s" % "\n".join(wrap("Second Title", width=60)))
  • For some reason I can get this solution to work with plot.fig.suptitle('some text' '\n' 'more text ' '\n' 'more text' + str(a string), fontsize = 12) but not with another string added between the text lines plot.fig.suptitle('some text' '\n' 'more text' + str(a strig) '\n' 'more text ' + str(a string), fontsize = 12). Any recommendations? – Christer Edvardsson Aug 25 '21 at 14:45
0

Add \n in your text title

Before

axs[0, 0].set_title('pure imshow of 2D-array (RGB)')
axs[0, 1].set_title('Mean filter')                                     # imshow by default applies a standard colormap,  viridis cmap, which is greenish. 
axs[0, 2].set_title('pure imshow of 2D-array (R-channel)')             # 
axs[1, 0].set_title('imshow of 2D-array with R values cmap="Grey_r"')
axs[1, 1].set_title('imshow of 2D-array with R values cmap="Reds_r"')
axs[1, 2].set_title('imshow of 3D-array with coordinates 1 and 2 \n(i.e.: channels G and B) set to 0')

After

axs[1, 0].set_title('imshow of 2D-array \n with R values cmap="Grey_r"')
axs[1, 1].set_title('imshow of 2D-array \n with R values cmap="Reds_r"')
axs[1, 2].set_title('imshow of 3D-array with coordinates 1 and 2 \n channels G and B) set to 0')