tight_layout() berücksichtigt den Bilduntertitel nicht

Lesezeit: 6 Minuten

Benutzeravatar von katrasnikj
katrasnikj

Wenn ich meiner Matplotlib-Abbildung einen Untertitel hinzufüge, wird er von den Titeln der Nebenhandlung überlagert. Weiß jemand, wie man das einfach in den Griff bekommt? Ich versuchte die tight_layout() funktionieren, aber es macht alles nur noch schlimmer.

Beispiel:

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.tight_layout()
plt.show()

Benutzeravatar von soupault
Suppensalto

Sie können die Subplot-Geometrie im Grunde anpassen tight_layout wie folgt anrufen:

fig.tight_layout(rect=[0, 0.03, 1, 0.95])

Wie es in der Dokumentation steht (https://matplotlib.org/users/tight_layout_guide.html):

tight_layout() berücksichtigt nur Ticklabels, Achsenbeschriftungen und Titel. Somit können andere Künstler abgeschnitten werden und sich auch überlappen.

  • Es hat wunderbar funktioniert, aber wie passiert die Änderung beim Festlegen des Begrenzungsrahmens? Ich habe die Doku gelesen, aber mir war nicht viel klar. Wäre toll, wenn du mir das bitte erklären könntest! Vielen Dank.

    – thepunitsingh

    24. November 2017 um 13:22 Uhr

  • Könnten Sie bitte die Bedeutung jeder Zahl im Rect erklären? Ich habe sie nicht in der Doku gesehen.

    – Stefan

    13. Mai 2019 um 21:41 Uhr

  • @steven siehe tight_layout Dokumente: [left, bottom, right, top] in normalized (0, 1) figure coordinates

    – Suppensalto

    14. Mai 2019 um 6:58 Uhr

  • Sie können den Abstand zwischen Untertitel und Achsen noch weiter vergrößern, indem Sie den rechten Wert verringern: tight_layout(rect=[0, 0.03, 1, 0.9]) Anstatt von 0.95 wie in der Antwort.

    – ComFreek

    24. September 2019 um 9:17 Uhr


  • Hat innerhalb von Jupyter nicht funktioniert. Verschiedene Werte für Zahlen probiert, hatte keine Wirkung

    – Aleksejs Fomins

    23. Januar 2020 um 14:22 Uhr

Sie können den Abstand manuell mit anpassen plt.subplots_adjust(top=0.85):

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.subplots_adjust(top=0.85)
plt.show()

  • Ich kann nicht an das Jahr 2017 unseres Herrn glauben, das ist immer noch ein Fehler von Matplotlib.

    – Worte für den Fall

    13. Januar 2017 um 23:28 Uhr

  • Beachten Sie, dass subplots_adjust muss angerufen werden nach alle Anrufe an tight_layoutoder der Aufruf hat keine Auswirkung subplots_adjust.

    – Achal Dave

    20. Januar 2017 um 18:58 Uhr

  • @wordsforthewise macht das jetzt 2018

    – vlsd

    16. März 2018 um 17:23 Uhr

  • @vlsd Hallo aus 2019

    – Xiaoyu Lu

    23. September 2019 um 4:02 Uhr

  • 2020 hier und das ist immer noch ein Thema

    – Thomas Tiotto

    21. Juni 2020 um 8:38 Uhr

Benutzeravatar von asagram
einagramm

Eine Sache, die Sie in Ihrem Code sehr einfach ändern könnten, ist die fontsize Sie verwenden für die Titel. Ich gehe jedoch davon aus, dass Sie das nicht wollen!

Einige Alternativen zur Verwendung fig.subplots_adjust(top=0.85):

Normalerweise tight_layout() macht einen ziemlich guten Job, alles an guten Orten zu positionieren, so dass sie sich nicht überlappen. Der Grund tight_layout() hilft in diesem Fall nicht, weil tight_layout() berücksichtigt fig.suptitle() nicht. Auf GitHub gibt es dazu ein offenes Problem: https://github.com/matplotlib/matplotlib/issues/829 [closed in 2014 due to requiring a full geometry manager – shifted to https://github.com/matplotlib/matplotlib/issues/1109 ].

Wenn du den Thread liest, ist dort eine Lösung für dein Problem mit dabei GridSpec. Der Schlüssel ist, beim Aufrufen oben in der Figur etwas Platz zu lassen tight_layoutVerwendung der rect kwarg. Für Ihr Problem wird der Code zu:

Verwenden von GridSpec

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

f = np.random.random(100)
g = np.random.random(100)

fig = plt.figure(1)
gs1 = gridspec.GridSpec(1, 2)
ax_list = [fig.add_subplot(ss) for ss in gs1]

ax_list[0].plot(f)
ax_list[0].set_title('Very Long Title 1', fontsize=20)

ax_list[1].plot(g)
ax_list[1].set_title('Very Long Title 2', fontsize=20)

fig.suptitle('Long Suptitle', fontsize=24)    

gs1.tight_layout(fig, rect=[0, 0.03, 1, 0.95])  

plt.show()

Das Ergebnis:

mit Gridspez

Vielleicht GridSpec ist ein bisschen übertrieben für Sie, oder Ihr wirkliches Problem wird viel mehr Nebenhandlungen auf einer viel größeren Leinwand oder andere Komplikationen beinhalten. Ein einfacher Hack ist einfach zu verwenden annotate() und sperren Sie die Koordinaten auf die 'figure fraction' a nachahmen suptitle. Möglicherweise müssen Sie jedoch einige feinere Anpassungen vornehmen, wenn Sie sich die Ausgabe ansehen. Beachten Sie, dass diese zweite Lösung dies tut nicht verwenden tight_layout().

Einfachere Lösung (Muss aber eventuell noch angepasst werden)

fig = plt.figure(2)

ax1 = plt.subplot(121)
ax1.plot(f)
ax1.set_title('Very Long Title 1', fontsize=20)

ax2 = plt.subplot(122)
ax2.plot(g)
ax2.set_title('Very Long Title 2', fontsize=20)

# fig.suptitle('Long Suptitle', fontsize=24)
# Instead, do a hack by annotating the first axes with the desired 
# string and set the positioning to 'figure fraction'.
fig.get_axes()[0].annotate('Long Suptitle', (0.5, 0.95), 
                            xycoords="figure fraction", ha="center", 
                            fontsize=24
                            )
plt.show()

Das Ergebnis:

einfach

[Using Python 2.7.3 (64-bit) and matplotlib 1.2.0]

  • Danke, wenn ich die erste von Ihnen vorgeschlagene Lösung verwende (mit GridSpec) Wie kann ich Subplots erstellen, die Achsen teilen? Ich benutze normalerweise plt.subplots(N,1, sharex=<>, sharey=<>) beim Erstellen von Nebenhandlungen, aber der von Ihnen gepostete Code verwendet add_subplot stattdessen

    – Amelio Vázquez-Reina

    19. März 2014 um 15:55 Uhr


  • Gießen fig.tight_layout(rect=[0, 0.03, 1, 0.95]) funktioniert auch.

    – Suppensalto

    16. September 2015 um 13:06 Uhr

  • Die zweite Lösung ist die einzige, die für mich funktioniert hat. Vielen Dank!

    – Hagbard

    9. März 2020 um 13:26 Uhr

bhayleys Benutzeravatar
bhayley

Enges Layout funktioniert nicht mit Untertiteln, aber constrained_layout tut. Siehe diese Frage Verbessern Sie die Größe / den Abstand von Subplots mit vielen Subplots in Matplotlib

Ich fand, dass das Hinzufügen der Nebenhandlungen auf einmal besser aussah, dh

fig, axs = plt.subplots(rows, cols, constrained_layout=True)

# then iterating over the axes to fill in the plots

Es kann aber auch bei der Erstellung der Figur hinzugefügt werden:

fig = plt.figure(constrained_layout=True)

ax1 = fig.add_subplot(cols, rows, 1)
# etc

Hinweis: Um meine Nebenhandlungen näher zusammenzubringen, habe ich auch verwendet

fig.subplots_adjust(wspace=0.05)

und constrained_layout funktioniert damit nicht 🙁

Eine alternative und einfach zu verwendende Lösung besteht darin, die Koordinaten des Untertiteltextes in der Abbildung mit dem y-Argument im Aufruf von suptitle anzupassen (siehe die Dokumente):

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', y=1.05, fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.show()

  • Dies ist eine großartige Möglichkeit in einem Notebook, aber der Befehl plt.savefig() gehorcht nicht. Diese Lösung schneidet immer noch den Titel in einem savefig-Befehl ab.

    – Superheld

    23. Juni 2016 um 10:17 Uhr

Benutzeravatar von Herman Schaaf
Hermann Schaf

Wie von anderen erwähnt, berücksichtigt das enge Layout standardmäßig keine Untertitel. Ich habe jedoch festgestellt, dass es möglich ist, die zu verwenden bbox_extra_artists Argument, um den Untertitel als Begrenzungsrahmen zu übergeben, der berücksichtigt werden sollte:

st = fig.suptitle("My Super Title")
plt.savefig("figure.png", bbox_extra_artists=[st], bbox_inches="tight")

Das zwingt die knappe Layout-Berechnung zum Mitnehmen suptitle berücksichtigt, und es sieht so aus, wie Sie es erwarten würden.

  • Dies ist eine großartige Möglichkeit in einem Notebook, aber der Befehl plt.savefig() gehorcht nicht. Diese Lösung schneidet immer noch den Titel in einem savefig-Befehl ab.

    – Superheld

    23. Juni 2016 um 10:17 Uhr

Benutzeravatar von aboger
übertreiben

Diese Internetseite hat eine einfache Lösung dafür mit einem Beispiel, das für mich funktioniert hat. Die Codezeile, die das eigentliche Freilassen des Platzes für den Titel ausführt, ist die folgende:

plt.tight_layout(rect=[0, 0, 1, 0.95]) 

Hier ist ein Beweisbild, dass es bei mir funktioniert hat:
Bildlink

1398960cookie-checktight_layout() berücksichtigt den Bilduntertitel nicht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy