2
sns.boxplot(data=df, width=0.5)
plt.title(f'Distribution of scores for initial and resubmission\
           \nonly among students who resubmitted at all.\
           \n(n = {df.shape[0]})')

I want to use a bigger font, and leave more space in the top white margin so that the title doesn't get crammed in. Surprisingly, I am totally unable to find the option despite some serious googling!

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
pitosalas
  • 10,286
  • 12
  • 72
  • 120
  • 1
    Possible duplicate of [Python Matplotlib figure title overlaps axes label when using twiny](https://stackoverflow.com/questions/12750355/python-matplotlib-figure-title-overlaps-axes-label-when-using-twiny) – ImportanceOfBeingErnest Apr 20 '18 at 22:06

1 Answers1

8

The basic problem you have is that the multi-line title is too tall, and is rendered "off the page".

A few options for you:

  • the least effort solution is probably to use tight_layout(). plt.tight_layout() manipulates the subplot locations and spacing so that labels, ticks and titles fit more nicely.

  • if this isn't enough, also look at plt.subplots_adjust() which gives you control over how much whitespace is used around one or more subfigures; you can modify just one aspect at at time, and all the other settings are left alone. In your case, you could use plt.subplots_adjust(top=0.8).

  • If you are generating a final figure for publication or similar, you might be aiming to tweak a lot to perfect it. In this case, you can precisely control the (sub)plot locations, using add_axes (see this example https://stackoverflow.com/a/17479417).

Here is an example, with a 6-line title for emphasis. The left panel shows the default - with half the title clipped off. The right panel has all measurements the same except the top; the middle has automatically removed whitespace on all sides.

improved title handling

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

data = 55 + 5* np.random.randn(1000,)    # some data
vlongtitle = "\n".join(["long title"]*6) # a 6-line title

# using tight_layout, all the margins are reduced
plt.figure()
sns.boxplot(data, width=0.5)
plt.title(vlongtitle)
plt.tight_layout()

# 2nd option, just edit one aspect.
plt.figure()
sns.boxplot(data, width=0.5)
plt.title(vlongtitle)
plt.subplots_adjust(top=0.72)
Bonlenfum
  • 19,101
  • 2
  • 53
  • 56