Tytuł rysunku w Pythonie Matplotlib nakłada się na etykietę osi podczas używania twiny

139

Próbuję wykreślić dwie oddzielne wielkości na tym samym wykresie za pomocą twiny w następujący sposób:

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()

a dane są prezentowane dobrze, ale mam problem, że tytuł figury nakłada się na etykiety osi na pomocniczej osi x tak, że jest ledwo czytelny (chciałem zamieścić tutaj przykładowe zdjęcie, ale nie mam wystarczająco wysoka liczba powtórzeń).

Chciałbym wiedzieć, czy istnieje prosty sposób, aby po prostu przesunąć tytuł bezpośrednio w górę o kilka dziesiątek pikseli, aby wykres wyglądał ładniej.

Magic_Matt_Man
źródło
1
Witamy w Stack Overflow! Jeśli umieścisz link do imgur publikującego twoje zdjęcie, użytkownik o wyższym stopniu reputacji osadzi obraz w twoim poście.
Hooked
@Magic - Czy zastanowisz się ponownie, jaką odpowiedź zaakceptować na to pytanie? Matplotlib dodał wbudowany mechanizm do obsługi tej konkretnej potrzeby (najczęściej głosowana odpowiedź poniżej)
Amelio Vazquez-Reina

Odpowiedzi:

243

Nie jestem pewien, czy jest to nowa funkcja w późniejszych wersjach matplotlib, ale przynajmniej dla 1.3.1 jest to po prostu:

plt.title(figure_title, y=1.08)

Działa to również dla plt.suptitle(), ale (jeszcze) dla plt.xlabel()itp.

herrlich10
źródło
6
W przypadku etykiet można ustawić argument labelpad, patrz tutaj .
Felix Hoffmann
1
Nie jest to nowa funkcja. titlebrał xi yargumentował przez bardzo długi czas (przynajmniej o ile pamiętam).
Joe Kington,
3
plt.set_title ('string title', y = 1.08) działa dla mnie.
Yu Shen
3
Byłoby bardziej pomocne, gdyby ktoś wyjaśnił, czym są jednostki 1.08 i jakie są wartości domyślne. Rozumiem, że wartość domyślna to 1
kon psych.
3
@JohnCummings Wygląda na to, że domyślną wartością jest y = 1, a jednostka to „ułamek osi”, tj. Y = 0,5 oznacza, że ​​tytuł znajduje się pośrodku osi, a y = 0 oznacza, że ​​tytuł znajduje się tuż nad dolną częścią osie.
herrlich10
33

Zapomnij o używaniu plt.titlei umieść tekst bezpośrednio za pomocą plt.text. Poniżej podano przesadzony przykład:

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()

wprowadź opis obrazu tutaj

Haczykowaty
źródło
@ user815423426 tak, tight_layoutnadal nie wygląda dobrze na niestandardowe miejsca docelowe. Może mógłbyś zgłosić błąd?
Hooked
2
Znalazłem rozwiązanie podczas używania tight_layout, przynajmniej podczas zapisywania wykresu za pomocą figure.savefig () . Jeśli title = plt.title(...)więc możesz określić ścisłe obramowanie wykresu wokół tytułu, używając opcji bbox_extra_artists:figure.savefig(filename, bbox_extra_artists=(title), bbox_inches='tight')
junkaholik.
10
ax.set_title('My Title\n', fontsize="15", color="red")
plt.imshow(myfile, origin="upper")

Jeśli umieścisz '\n'bezpośrednio po tytule, wykres jest rysowany tuż pod tytułem. To też może być szybkie rozwiązanie.

Efkan
źródło
8

Miałem problem z etykietą x nakładającą się na tytuł wątku pomocniczego; to zadziałało dla mnie:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1)
ax[0].scatter(...)
ax[1].scatter(...)
plt.tight_layout()
.
.
.
plt.show()

przed

wprowadź opis obrazu tutaj

po

wprowadź opis obrazu tutaj

odniesienie:

jmunsch
źródło
4

Po prostu użyj plt.tight_layout()wcześniej plt.show(). To dobrze działa.

Peter Zhu
źródło
4

Możesz użyć podkładki w tym przypadku:

ax.set_title("whatever", pad=20)
Radvin
źródło