Matplotlib-Anwendungsschnittstellen (APIs) #
Matplotlib hat zwei Hauptanwendungsschnittstellen oder Arten der Verwendung der Bibliothek:
Eine explizite „Axes“-Schnittstelle, die Methoden auf einem Figure- oder Axes-Objekt verwendet, um andere Künstler zu erstellen und Schritt für Schritt eine Visualisierung zu erstellen. Dies wurde auch als "objektorientierte" Schnittstelle bezeichnet.
Eine implizite "Pyplot"-Schnittstelle, die die zuletzt erstellten Figuren und Achsen verfolgt und Künstler zu dem Objekt hinzufügt, von dem sie glaubt, dass der Benutzer es haben möchte.
Darüber hinaus bieten eine Reihe nachgelagerter Bibliotheken (wie pandas
und xarray ) eine plot
Methode an, die direkt in ihren Datenklassen implementiert ist, sodass Benutzer aufrufen können data.plot()
.
Der Unterschied zwischen diesen Schnittstellen kann etwas verwirrend sein, insbesondere angesichts von Snippets im Web, die die eine oder andere oder manchmal mehrere Schnittstellen im selben Beispiel verwenden. Hier versuchen wir aufzuzeigen, wie sich die „pyplot“- und Downstream-Schnittstellen auf die explizite „Axes“-Schnittstelle beziehen, um den Benutzern zu helfen, sich besser in der Bibliothek zurechtzufinden.
Native Matplotlib-Schnittstellen #
Die explizite "Achsen"-Schnittstelle #
Matplotlib wird über die Schnittstelle „Axes“ implementiert, und viele Anpassungen und Feinabstimmungen werden auf dieser Ebene vorgenommen.
Diese Schnittstelle funktioniert, indem sie eine Instanz einer
Figure
Klasse ( fig
unten) instanziiert, eine
subplots
Methodenmethode (oder ähnliches) für dieses Objekt verwendet, um ein oder mehrere
Axes
Objekte ( ax
unten) zu erstellen, und dann Zeichenmethoden für die Achsen aufruft ( plot
in diesem Beispiel):
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.subplots()
ax.plot([1, 2, 3, 4], [0, 0.5, 1, 0.2])
Wir nennen dies eine "explizite" Schnittstelle, weil jedes Objekt explizit referenziert und verwendet wird, um das nächste Objekt zu erstellen. Das Beibehalten von Verweisen auf die Objekte ist sehr flexibel und ermöglicht es uns, die Objekte anzupassen, nachdem sie erstellt wurden, aber bevor sie angezeigt werden.
Die implizite "pyplot"-Schnittstelle #
Das pyplot
Modul schattiert die meisten
Axes
Zeichenmethoden, um das Äquivalent zu den oben genannten zu erhalten, wobei die Erstellung der Figur und der Achsen für den Benutzer erfolgt:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [0, 0.5, 1, 0.2])
Dies kann praktisch sein, insbesondere bei interaktiven Arbeiten oder einfachen Skripten. Ein Verweis auf die aktuelle Figur kann mit
gcf
und auf die aktuellen Achsen mit abgerufen werden gca
. Das pyplot
Modul behält eine Liste von Figuren, und jede Figur behält eine Liste von Achsen auf der Figur für den Benutzer, so dass Folgendes gilt:
import matplotlib.pyplot as plt
plt.subplot(1, 2, 1)
plt.plot([1, 2, 3], [0, 0.5, 0.2])
plt.subplot(1, 2, 2)
plt.plot([3, 2, 1], [0, 0.5, 0.2])
ist äquivalent zu:
import matplotlib.pyplot as plt
plt.subplot(1, 2, 1)
ax = plt.gca()
ax.plot([1, 2, 3], [0, 0.5, 0.2])
plt.subplot(1, 2, 2)
ax = plt.gca()
ax.plot([3, 2, 1], [0, 0.5, 0.2])
In der expliziten Schnittstelle wäre dies:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 2)
axs[0].plot([1, 2, 3], [0, 0.5, 0.2])
axs[1].plot([3, 2, 1], [0, 0.5, 0.2])
Warum explizit sein? #
Was passiert, wenn Sie zurückgehen und auf einer alten Achse arbeiten müssen, die nicht von referenziert wird plt.gca()
? Eine einfache Möglichkeit besteht darin, subplot
mit denselben Argumenten erneut aufzurufen. Das wird aber schnell unelegant. Sie können auch das Figure-Objekt untersuchen und seine Liste der Axes-Objekte abrufen, was jedoch irreführend sein kann (Farbbalken sind auch Axes!). Die beste Lösung ist wahrscheinlich, ein Handle für jede von Ihnen erstellte Achse zu speichern, aber wenn Sie das tun, warum erstellen Sie dann nicht einfach alle Axes-Objekte am Anfang?
Der erste Ansatz besteht darin, erneut anzurufen plt.subplot
:
import matplotlib.pyplot as plt
plt.subplot(1, 2, 1)
plt.plot([1, 2, 3], [0, 0.5, 0.2])
plt.subplot(1, 2, 2)
plt.plot([3, 2, 1], [0, 0.5, 0.2])
plt.suptitle('Implicit Interface: re-call subplot')
for i in range(1, 3):
plt.subplot(1, 2, i)
plt.xlabel('Boo')
Die zweite besteht darin, ein Handle zu speichern:
import matplotlib.pyplot as plt
axs = []
ax = plt.subplot(1, 2, 1)
axs += [ax]
plt.plot([1, 2, 3], [0, 0.5, 0.2])
ax = plt.subplot(1, 2, 2)
axs += [ax]
plt.plot([3, 2, 1], [0, 0.5, 0.2])
plt.suptitle('Implicit Interface: save handles')
for i in range(2):
plt.sca(axs[i])
plt.xlabel('Boo')
Der empfohlene Weg wäre jedoch, von Anfang an explizit zu sein:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 2)
axs[0].plot([1, 2, 3], [0, 0.5, 0.2])
axs[1].plot([3, 2, 1], [0, 0.5, 0.2])
fig.suptitle('Explicit Interface')
for i in range(2):
axs[i].set_xlabel('Boo')
"Datenobjekt"-Schnittstellen von Drittanbieter-Bibliotheken #
Einige Bibliotheken von Drittanbietern haben sich entschieden, das Plotten für ihre Datenobjekte zu implementieren, z. B. data.plot()
wird in pandas
, xarray und anderen Bibliotheken von Drittanbietern angezeigt. Zur Veranschaulichung kann eine Downstream-Bibliothek einen einfachen Datencontainer implementieren, in dem Daten x
und y
Daten zusammen gespeichert sind, und dann eine plot
Methode implementieren:
import matplotlib.pyplot as plt
# supplied by downstream library:
class DataContainer:
def __init__(self, x, y):
"""
Proper docstring here!
"""
self._x = x
self._y = y
def plot(self, ax=None, **kwargs):
if ax is None:
ax = plt.gca()
ax.plot(self._x, self._y, **kwargs)
ax.set_title('Plotted from DataClass!')
return ax
# what the user usually calls:
data = DataContainer([0, 1, 2, 3], [0, 0.2, 0.5, 0.3])
data.plot()
So kann die Bibliothek alle Einzelheiten vor dem Benutzer verbergen und eine dem Datentyp angemessene Visualisierung erstellen, oft mit guten Beschriftungen, einer Auswahl an Farbkarten und anderen praktischen Funktionen.
Oben hat uns jedoch möglicherweise der von der Bibliothek bereitgestellte Titel nicht gefallen. Glücklicherweise geben sie uns die Axes aus der plot()
Methode zurück, und wenn wir die explizite Axes-Schnittstelle verstehen, könnten wir aufrufen:
um den Titel anzupassen.ax.set_title('My preferred title')
Viele Bibliotheken erlauben ihren plot
Methoden auch, ein optionales ax -
Argument zu akzeptieren. Auf diese Weise können wir die Visualisierung in einer von uns platzierten und möglicherweise angepassten Achse platzieren.
Zusammenfassung #
Insgesamt ist es hilfreich, die explizite „Axes“-Schnittstelle zu verstehen, da sie die flexibelste ist und den anderen Schnittstellen zugrunde liegt. Ein Benutzer kann normalerweise herausfinden, wie er zur expliziten Schnittstelle herunterfällt und die zugrunde liegenden Objekte bearbeitet. Während die Einrichtung der expliziten Schnittstelle etwas ausführlicher sein kann, sind komplizierte Plots oft einfacher als der Versuch, die implizite "Pyplot" -Schnittstelle zu verwenden.
Notiz
Es ist manchmal verwirrend, dass wir pyplot
für beide Schnittstellen importieren. Derzeit pyplot
implementiert das Modul die "pyplot"-Schnittstelle, bietet aber auch Top-Level-Erstellungsmethoden für Figuren und Achsen und dreht schließlich die grafische Benutzeroberfläche hoch, falls eine verwendet wird. Wird also pyplot
immer noch benötigt, unabhängig von der gewählten Schnittstelle.
In ähnlicher Weise verwenden die von Partnerbibliotheken bereitgestellten deklarativen Schnittstellen die Objekte, auf die über die Schnittstelle „Axes“ zugegriffen werden kann, und akzeptieren diese häufig als Argumente oder geben sie von Methoden zurück. Normalerweise ist es wichtig, die explizite „Axes“-Schnittstelle zu verwenden, um Anpassungen an der Standardvisualisierung vorzunehmen oder die Daten in NumPy-Arrays zu entpacken und direkt an Matplotlib zu übergeben.
Anhang: Schnittstelle "Achsen" mit Datenstrukturen #
Die meisten Axes
Methoden erlauben noch eine weitere API-Adressierung, indem sie ein
Datenobjekt an die Methode übergeben und die Argumente als Strings angeben:
import matplotlib.pyplot as plt
data = {'xdat': [0, 1, 2, 3], 'ydat': [0, 0.2, 0.4, 0.1]}
fig, ax = plt.subplots(figsize=(2, 2))
ax.plot('xdat', 'ydat', data=data)
Anhang: "pylab"-Schnittstelle #
Es gibt eine weitere Schnittstelle, von der dringend abgeraten wird, und das ist im Grunde genommen . Dadurch können Benutzer einfach anrufen . Dies ist zwar praktisch, kann aber zu offensichtlichen Problemen führen, wenn der Benutzer einer Variablen unwissentlich denselben Namen wie einer Pyplot-Methode gibt.from matplotlib.pyplot import *
plot(x, y)