Häufig gestellte Fragen#

Ich sehe kein Fenster für die Abbildung

Bitte siehe Fehlerbehebung bei nicht angezeigten Abbildungsfenstern.

Warum habe ich so viele Achsenmarkierungen, und/oder warum sind sie nicht in der richtigen Reihenfolge?#

Eine häufige Ursache für unerwartetes Verhalten bei Achsenmarkierungen ist die Übergabe einer *Liste von Zeichenketten anstelle von Zahlen oder Datums-/Zeitobjekten*. Dies kann leicht unbemerkt geschehen, wenn eine Textdatei mit Kommas als Trennzeichen eingelesen wird. Matplotlib behandelt Listen von Zeichenketten als *kategoriale* Variablen (Darstellung kategorialer Variablen) und setzt standardmäßig eine Achsenmarkierung pro Kategorie und plottet sie in der Reihenfolge, in der sie übergeben werden.

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(1, 2, layout='constrained', figsize=(6, 2))

ax[0].set_title('Ticks seem out of order / misplaced')
x = ['5', '20', '1', '9']  # strings
y = [5, 20, 1, 9]
ax[0].plot(x, y, 'd')
ax[0].tick_params(axis='x', labelcolor='red', labelsize=14)

ax[1].set_title('Many ticks')
x = [str(xx) for xx in np.arange(100)]  # strings
y = np.arange(100)
ax[1].plot(x, y)
ax[1].tick_params(axis='x', labelcolor='red', labelsize=14)

(Quellcode, 2x.png, png)

Die Lösung besteht darin, die Liste von Zeichenketten in Zahlen oder Datums-/Zeitobjekte zu konvertieren (oftmals np.asarray(numeric_strings, dtype='float') oder np.asarray(datetime_strings, dtype='datetime64[s]')).

Weitere Informationen finden Sie unter Behebung von zu vielen Achsenmarkierungen.

Bestimmen der Ausdehnung von Künstlern in der Abbildung

Manchmal möchten wir die Ausdehnung eines Künstlers erfahren. Matplotlib Artist-Objekte haben eine Methode Artist.get_window_extent, die normalerweise die Ausdehnung des Künstlers in Pixeln zurückgibt. Einige Künstler, insbesondere Text, müssen jedoch mindestens einmal gerendert werden, bevor ihre Ausdehnung bekannt ist. Matplotlib stellt Figure.draw_without_rendering zur Verfügung, die aufgerufen werden sollte, bevor get_window_extent aufgerufen wird.

Prüfen, ob eine Abbildung leer ist

Leer kann tatsächlich unterschiedliche Bedeutungen haben. Enthält die Abbildung Künstler? Zählt eine Abbildung mit einem leeren Axes immer noch als leer? Ist die Abbildung leer, wenn sie rein weiß gerendert wurde (es können Künstler vorhanden sein, aber sie könnten außerhalb des Zeichenbereichs oder transparent sein)?

Für den Zweck hier definieren wir leer als: "Die Abbildung enthält keine Künstler außer ihrem Hintergrundrechteck." Die Ausnahme für den Hintergrund ist notwendig, da standardmäßig jede Abbildung ein Rectangle als Hintergrundrechteck enthält. Diese Definition könnte wie folgt überprüft werden:

def is_empty(figure):
    """
    Return whether the figure contains no Artists (other than the default
    background patch).
    """
    contained_artists = figure.get_children()
    return len(contained_artists) <= 1

Wir haben uns entschieden, dies nicht als Methode der Abbildung aufzunehmen, da dies nur eine Möglichkeit ist, "leer" zu definieren, und die obige Prüfung nur selten notwendig ist. Normalerweise weiß der Benutzer oder das Programm, das die Abbildung verwaltet, ob etwas zur Abbildung hinzugefügt wurde.

Der einzig zuverlässige Weg zu prüfen, ob eine Abbildung leer gerendert würde, ist, eine solche Renderung tatsächlich durchzuführen und das Ergebnis zu untersuchen.

Alle Objekte eines bestimmten Typs in einer Abbildung finden

Jeder Matplotlib-Künstler (siehe Künstler-Tutorial) hat eine Methode namens findobj(), die verwendet werden kann, um rekursiv nach Künstlern zu suchen, die bestimmte Kriterien erfüllen (z. B. alle Line2D-Instanzen entsprechen oder einer beliebigen Filterfunktion entsprechen). Zum Beispiel findet der folgende Ausschnitt jedes Objekt in der Abbildung, das eine Eigenschaft set_color hat, und macht das Objekt blau

def myfunc(x):
    return hasattr(x, 'set_color')

for o in fig.findobj(myfunc):
    o.set_color('blue')

Sie können auch nach Klasseninstanzen filtern

import matplotlib.text as text
for o in fig.findobj(text.Text):
    o.set_fontstyle('italic')

Verhindern, dass Achsenbeschriftungen einen Offset haben

Der Standardformatierer verwendet einen Offset, um die Länge der Achsenbeschriftungen zu reduzieren. Um diese Funktion pro Achse zu deaktivieren

ax.xaxis.get_major_formatter().set_useOffset(False)

setzen Sie rcParams["axes.formatter.useoffset"] (Standard: True) oder verwenden Sie einen anderen Formatierer. Weitere Details finden Sie unter ticker.

Transparente Abbildungen speichern

Der Befehl savefig() hat ein Schlüsselwortargument *transparent*, das, wenn es auf 'True' gesetzt ist, die Hintergründe der Abbildung und der Achsen beim Speichern transparent macht, aber das angezeigte Bild auf dem Bildschirm nicht beeinflusst.

Wenn Sie eine feinere Kontrolle benötigen, z. B. wenn Sie keine vollständige Transparenz wünschen oder auch die angezeigte Bildschirmversion beeinflussen möchten, können Sie die Alpha-Eigenschaften direkt setzen. Die Abbildung hat eine Rectangle-Instanz namens *patch* und die Achsen haben eine Rectangle-Instanz namens *patch*. Sie können jede Eigenschaft direkt darauf setzen ( *facecolor*, *edgecolor*, *linewidth*, *linestyle*, *alpha*). Zum Beispiel

fig = plt.figure()
fig.patch.set_alpha(0.5)
ax = fig.add_subplot(111)
ax.patch.set_alpha(0.5)

Wenn Sie möchten, dass *alle* Abbildungselemente transparent sind, gibt es derzeit keine globale Alpha-Einstellung, aber Sie können den Alpha-Kanal für einzelne Elemente setzen, z. B.

ax.plot(x, y, alpha=0.5)
ax.set_xlabel('volts', alpha=0.5)

Mehrere Plots in einer PDF-Datei speichern

Viele Bilddateiformate können nur ein Bild pro Datei enthalten, aber einige Formate unterstützen mehrseitige Dateien. Derzeit bietet Matplotlib nur mehrseitige Ausgaben für PDF-Dateien, entweder mit den PDF- oder PGF-Backends, über die Klassen backend_pdf.PdfPages und backend_pgf.PdfPages.

Platz für Achsenbeschriftungen schaffen

Standardmäßig verwendet Matplotlib feste prozentuale Ränder um Subplots. Dies kann dazu führen, dass Beschriftungen überlappen oder am Abbildungrand abgeschnitten werden. Es gibt mehrere Möglichkeiten, dies zu beheben

Y-Achsenbeschriftungen über mehrere Subplots hinweg ausrichten

Wenn Sie mehrere Subplots übereinander haben und die Y-Daten unterschiedliche Skalen aufweisen, kann es vorkommen, dass sich die Y-Achsenbeschriftungen nicht vertikal über die mehreren Subplots hinweg ausrichten, was unschön aussehen kann. Standardmäßig positioniert Matplotlib die X-Position der Y-Achsenbeschriftung so, dass sie keine der Y-Achsenmarkierungen überlappt. Dieses Standardverhalten können Sie überschreiben, indem Sie die Koordinaten der Beschriftung angeben. Wie das geht, erfahren Sie unter Y-Achsenbeschriftungen ausrichten

Reihenfolge der Plot-Elemente beim Zeichnen steuern

Die Zeichenreihenfolge von Plot-Elementen und damit, welche Elemente oben liegen, wird durch die Eigenschaft set_zorder bestimmt. Eine detaillierte Beschreibung finden Sie in Zorder Demo.

Seitenverhältnis für Plots gleich machen

Die Achsen-Eigenschaft set_aspect() steuert das Seitenverhältnis der Achsen. Sie können es auf 'auto', 'equal' oder ein beliebiges Verhältnis setzen, das das Verhältnis steuert.

ax = fig.add_subplot(111, aspect='equal')

Ein vollständiges Beispiel finden Sie unter Gleiches Achsen-Seitenverhältnis.

Mehrere Y-Achsen-Skalen zeichnen

Eine häufige Anforderung ist, zwei Skalen für die linke und rechte Y-Achse zu haben, was mit twinx() möglich ist (mehr als zwei Skalen werden derzeit nicht unterstützt, obwohl sie auf der Wunschliste stehen). Dies funktioniert ziemlich gut, obwohl es einige Eigenheiten gibt, wenn Sie versuchen, interaktiv zu schwenken und zu zoomen, da beide Skalen nicht die Signale erhalten.

Der Ansatz verwendet twinx() (und seinen Schwesterbefehl twiny()), um *2 verschiedene Achsen* zu verwenden, den rechteckigen Rahmen der Achsen auf der 2. Achse auszuschalten, damit sie die erste nicht verdeckt, und die Achsenmarkierungen und -beschriftungen manuell nach Wunsch einzustellen. Sie können separate matplotlib.ticker Formatierer und Locators nach Belieben verwenden, da die beiden Achsen unabhängig sind.

(Quellcode, 2x.png, png)

Ein vollständiges Beispiel finden Sie unter Plots mit unterschiedlichen Skalen.

Bilder generieren, ohne dass ein Fenster erscheint

Rufen Sie einfach nicht show auf und speichern Sie die Abbildung direkt im gewünschten Format.

import matplotlib.pyplot as plt
plt.plot([1, 2, 3])
plt.savefig('myfig.png')
plt.close()

Siehe auch

Einbetten in einen Webanwendungs-Server (Flask) für Informationen zur Ausführung von Matplotlib innerhalb einer Webanwendung.

Mit Threads arbeiten

Matplotlib ist nicht Thread-sicher: Tatsächlich gibt es bekannte Race Conditions, die bestimmte Künstler betreffen. Daher sind Sie bei der Arbeit mit Threads dafür verantwortlich, die richtigen Sperren einzurichten, um den Zugriff auf Matplotlib-Künstler zu serialisieren.

Sie können möglicherweise mit separaten Abbildungen aus separaten Threads arbeiten. In diesem Fall müssen Sie jedoch ein *nicht-interaktives Backend* (typischerweise Agg) verwenden, da die meisten GUI-Backends *erfordern*, dass sie auch vom Hauptthread aus ausgeführt werden.

Hilfe erhalten

Es gibt eine Reihe von guten Ressourcen, um Hilfe bei Matplotlib zu erhalten. Es besteht eine gute Chance, dass Ihre Frage bereits gestellt wurde

Wenn Sie keine Antwort auf Ihre Frage finden können, indem Sie suchen, geben Sie bitte die folgenden Informationen in Ihrer E-Mail an die Mailingliste an

  • Ihr Betriebssystem (Linux/Unix-Benutzer: geben Sie die Ausgabe von uname -a aus).

  • Matplotlib-Version

    python -c "import matplotlib; print(matplotlib.__version__)"
    
  • Woher Sie Matplotlib bezogen haben (z. B. die Pakete Ihrer Linux-Distribution, GitHub, PyPI oder Anaconda).

  • Alle Anpassungen Ihrer matplotlibrc-Datei (siehe Matplotlib anpassen mit Style Sheets und rcParams).

  • Wenn das Problem reproduzierbar ist, versuchen Sie bitte, ein *minimales*, eigenständiges Python-Skript bereitzustellen, das das Problem demonstriert. Dies ist *der* entscheidende Schritt. Wenn Sie keinen Code posten können, den wir ausführen und Ihren Fehler reproduzieren können, sind die Chancen, Hilfe zu erhalten, erheblich geringer. Sehr oft hilft Ihnen allein die Tatsache, Ihren Code auf das kleinste Stück zu reduzieren, das den Fehler hervorruft, einen Fehler in *Ihrem* Code zu finden, der das Problem verursacht.

  • Matplotlib bietet Debugging-Informationen über die Bibliothek logging und eine Hilfsfunktion zum Einstellen des Logging-Levels: Man kann aufrufen

    plt.set_loglevel("info")  # or "debug" for more info
    

    um diese Debugging-Informationen zu erhalten.

    Standardfunktionen aus dem Modul logging sind ebenfalls anwendbar; z. B. könnte man logging.basicConfig(level="DEBUG") aufrufen, noch bevor Matplotlib importiert wird (dies ist insbesondere notwendig, um die Logging-Informationen zu erhalten, die während des Imports von Matplotlib ausgegeben werden), oder einen benutzerdefinierten Handler an den "matplotlib"-Logger anhängen. Dies kann nützlich sein, wenn Sie eine benutzerdefinierte Logging-Konfiguration verwenden.

Wenn Sie Matplotlib selbst kompiliert haben, stellen Sie bitte auch Folgendes bereit

  • Ihre Compiler-Version -- z. B. gcc --version.

  • die Ausgabe von

    pip install --verbose
    

    Der Anfang der Build-Ausgabe enthält viele Details zu Ihrer Plattform, die für die Matplotlib-Entwickler zur Diagnose Ihres Problems nützlich sind.

Wenn Sie eine ältere Version von Matplotlib mit dem Pre-Meson-Build-System kompiliert haben, stellen Sie stattdessen Folgendes bereit:

  • alle Änderungen, die Sie an setup.py/setupext.py vorgenommen haben,

  • die Ausgabe von

    rm -rf build
    python setup.py build
    

Die Aufnahme dieser Informationen in Ihre erste E-Mail an die Mailingliste spart viel Zeit.

Sie werden wahrscheinlich eine schnellere Antwort erhalten, wenn Sie an die Mailingliste schreiben, als wenn Sie einen Bug im Bug-Tracker melden. Die meisten Entwickler überprüfen den Bug-Tracker nur sporadisch. Wenn sich herausstellt, dass Ihr Problem ein Bug ist und nicht schnell gelöst werden kann, werden Sie möglicherweise aufgefordert, einen Bug im Tracker zu melden, damit das Problem nicht untergeht.