Python Matplotlib figure title overlaps axes label when using twiny
Solution 1
I'm not sure whether it is a new feature in later versions of matplotlib, but at least for 1.3.1, this is simply:
plt.title(figure_title, y=1.08)
This also works for plt.suptitle()
, but not (yet) for plt.xlabel()
, etc.
Solution 2
Forget using plt.title
and place the text directly with plt.text
. An over-exaggerated example is given below:
import pylab as plt
fig = plt.figure(figsize=(5,10))
figure_title = "Normal title"
ax1 = plt.subplot(1,2,1)
plt.title(figure_title, fontsize = 20)
plt.plot([1,2,3],[1,4,9])
figure_title = "Raised title"
ax2 = plt.subplot(1,2,2)
plt.text(0.5, 1.08, figure_title,
horizontalalignment='center',
fontsize=20,
transform = ax2.transAxes)
plt.plot([1,2,3],[1,4,9])
plt.show()
Solution 3
I was having an issue with the x-label overlapping a subplot title; this worked for me:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1)
ax[0].scatter(...)
ax[1].scatter(...)
plt.tight_layout()
.
.
.
plt.show()
before
after
reference:
Solution 4
ax.set_title('My Title\n', fontsize="15", color="red")
plt.imshow(myfile, origin="upper")
If you put '\n'
right after your title string, the plot is drawn just below the title. That might be a fast solution too.
Solution 5
You can use pad for this case:
ax.set_title("whatever", pad=20)
Related videos on Youtube
Magic_Matt_Man
Updated on July 08, 2022Comments
-
Magic_Matt_Man almost 2 years
I am trying to plot two separate quantities on the same graph using twiny as follows:
fig = figure() ax = fig.add_subplot(111) ax.plot(T, r, 'b-', T, R, 'r-', T, r_geo, 'g-') ax.set_yscale('log') ax.annotate('Approx. sea level', xy=(Planet.T_day*1.3,(Planet.R)/1000), xytext=(Planet.T_day*1.3, Planet.R/1000)) ax.annotate('Geostat. orbit', xy=(Planet.T_day*1.3, r_geo[0]), xytext=(Planet.T_day*1.3, r_geo[0])) ax.set_xlabel('Rotational period (hrs)') ax.set_ylabel('Orbital radius (km), logarithmic') ax.set_title('Orbital charts for ' + Planet.N, horizontalalignment='center', verticalalignment='top') ax2 = ax.twiny() ax2.plot(v,r,'k-') ax2.set_xlabel('Linear speed (ms-1)') show()
and the data is presented fine, but I am having the problem that the figure title is overlapping with the axes labels on the secondary x axis so that it's barely legible (I wanted to post a picture example here, but I don't have a high enough rep yet).
I'd like to know if there's a straightforward way to just shift the title directly up a few tens of pixels, so that the chart looks prettier.
-
Hooked over 11 yearsWelcome to Stack Overflow! If you link to an imgur posting of your picture a higher rep user will embed the image in your post for you.
-
Amelio Vazquez-Reina over 9 years@Magic -- Would you reconsider what answer to accept for this question? Matplotlib has added a builtin mechanism to handle this precise need (the most voted answer below)
-
-
Hooked about 10 years@user815423426 yes,
tight_layout
still doesn't seem to play nicely with non-standard placements. Perhaps you could make a bug report? -
Felix Hoffmann about 10 yearsFor labels you can set the argument
labelpad
, see here. -
Joe Kington over 9 yearsFor what it's worth, it's not a new feature.
title
has takenx
andy
arguments for a very long time (as long as I can remember, at any rate). -
Yu Shen over 9 yearsplt.set_title('title string', y = 1.08) works for me.
-
junkaholik about 9 yearsI found a work around when using tight_layout, at least when you save your plot using figure.savefig(). If
title = plt.title(...)
then you can specify to frame the plot tightly around the title using the optionbbox_extra_artists
:figure.savefig(filename, bbox_extra_artists=(title), bbox_inches='tight')
-
kon psych almost 7 yearsIt would be more helpful if someone explained what units 1.08 is and what are the defaults. My understanding is that default is 1
-
John Cummings over 6 years@konpsych I agree, the default is actually 0 according to the Text object docs but I'm not sure what units are.
-
herrlich10 over 6 years@JohnCummings It seems that the default value is y=1 and the units is "axes fraction", i.e., y=0.5 means the title is in the middle of the axes, and y=0 means the title is just above the bottom of the axes.
-
John Cummings over 6 years@herrlich10 thank you for the information on the units - where did you find that detail? Also, the only default I see for y is
y=0
in the Text object docs that I linked to. Where did you findy=1
as the default value? -
herrlich10 over 6 years@JohnCummings It's in the source code of
_AxesBase
class. Search for "self.title" in the file. -
Henrik almost 3 yearsThis works when iterating through axes too.