Backend schreiben -- die pyplot-Schnittstelle#
Diese Seite setzt ein allgemeines Verständnis der Informationen auf der Seite Backends voraus und dient stattdessen als Referenz für Implementierer von Drittanbieter-Backends. Sie behandelt auch nur die Interaktion zwischen Backends und pyplot, nicht die Rendering-Seite, die in backend_template beschrieben wird.
Es gibt zwei APIs zur Definition von Backends: eine neue Canvas-basierte API (eingeführt in Matplotlib 3.6) und eine ältere Funktions-basierte API. Die neue API ist einfacher zu implementieren, da viele Methoden von "Eltern-Backends" geerbt werden können. Sie wird empfohlen, wenn die Rückwärtskompatibilität für Matplotlib < 3.6 keine Rolle spielt. Die alte API bleibt jedoch weiterhin unterstützt.
Grundsätzlich muss ein Backend-Modul Informationen für pyplot bereitstellen, damit
pyplot.figure()eine neueFigure-Instanz erstellen und diese mit einer Instanz einer vom Backend bereitgestellten Canvas-Klasse verknüpfen kann, die selbst in einer Instanz einer vom Backend bereitgestellten Manager-Klasse gehostet wird.pyplot.show()kann alle Figuren anzeigen und die GUI-Ereignisschleife starten (falls vorhanden).
Dazu muss das Backend-Modul eine backend_module.FigureCanvas-Unterklasse von FigureCanvasBase definieren. In der Canvas-basierten API ist dies die einzige zwingende Anforderung für Backend-Module. Die Funktions-basierte API erfordert zusätzlich die Definition vieler Funktionen auf Modulebene.
Canvas-basierte API (Matplotlib >= 3.6)#
Figur erstellen:
pyplot.figure()ruftfigure = Figure(); FigureCanvas.new_manager(figure, num)(eine Klassenmethode) auf, um eine Canvas und einen Manager zu instanziieren und die Attributefigure.canvasundfigure.canvas.managereinzurichten. Das Entpickeln von Figuren verwendet den gleichen Ansatz, ersetzt aber die neu instanziierteFigure()durch die entpickelte Figur.Interaktive Backends sollten die Auswirkung von
new_manageranpassen, indem sie das AttributFigureCanvas.manager_classauf die gewünschte Manager-Klasse setzen und zusätzlich (falls die Canvas nicht vor dem Manager erstellt werden kann, wie bei wx-Backends) die KlassenmethodeFigureManager.create_with_canvasüberschreiben. (Nicht-interaktive Backends können normalerweise ein trivialesFigureManagerBaseverwenden und können diesen Schritt daher überspringen.)Nachdem eine neue Figur bei
pyplotregistriert wurde (entweder überpyplot.figure()oder über Entpickeln), ruftpyplotim interaktiven Modus die Methodedraw_idle()der Canvas auf, die nach Wunsch überschrieben werden kann.Figuren anzeigen:
pyplot.show()ruft die KlassenmethodeFigureCanvas.manager_class.pyplot_show()auf und übergibt alle Argumente, um die Haupt-Ereignisschleife zu starten.Standardmäßig prüft
pyplot_show(), ob beipyplotirgendwelchemanagerregistriert sind (und beendet frühzeitig, falls nicht), ruftmanager.show()für alle solchen Manager auf und ruft dann, wenn mitblock=True(oder mit dem Standardblock=Noneund außerhalb des IPython-pylab-Modus und nicht im interaktiven Modus) aufgerufen, die KlassenmethodeFigureCanvas.manager_class.start_main_loop()auf, um die Haupt-Ereignisschleife zu starten. Interaktive Backends sollten daher die KlassenmethodeFigureCanvas.manager_class.start_main_loopentsprechend überschreiben (oder alternativ können sie auch direktFigureCanvas.manager_class.pyplot_showüberschreiben).
Funktions-basierte API#
Figur erstellen:
pyplot.figure()ruftnew_figure_manager(num, *args, **kwargs)auf (die sich auch um die Erstellung der neuen Figur alsFigure(*args, **kwargs)kümmert); das Entpickeln ruftnew_figure_manager_given_figure(num, figure)auf.Darüber hinaus kann im interaktiven Modus die erste Darstellung der neu registrierten Figur durch Angabe einer Funktion
draw_if_interactive()auf Modulebene angepasst werden. (In der neuen Canvas-basierten API wird diese Funktion nicht mehr berücksichtigt.)Figuren anzeigen:
pyplot.show()ruft eine Funktionshow()auf Modulebene auf, die typischerweise über die KlasseShowBaseund ihre Methodemainloopgeneriert wird.
Ein Backend registrieren#
Damit ein neues Backend über matplotlib.use() oder den IPython %matplotlib Magic-Befehl verwendet werden kann, muss es mit einer der drei von BackendRegistry unterstützten Arten kompatibel sein.
Integriert#
Ein in Matplotlib integriertes Backend muss seinen Namen und FigureCanvas.required_interactive_framework fest in der BackendRegistry kodiert haben. Wenn das Backend-Modul nicht f"matplotlib.backends.backend_{backend_name.lower()}" ist, muss es auch einen Eintrag in BackendRegistry._name_to_module geben.
module:// Syntax#
Jedes Backend in einem separaten Modul (nicht in Matplotlib integriert) kann verwendet werden, indem der Pfad zum Modul in der Form module://some.backend.module angegeben wird. Ein Beispiel ist module://mplcairo.qt für mplcairo. Das interaktive Framework des Backends wird von seinem FigureCanvas.required_interactive_framework übernommen.
Einstiegspunkt#
Ein externes Backend-Modul kann sich selbst als Backend registrieren, indem es einen entry point in seiner pyproject.toml verwendet, wie z. B. bei matplotlib-inline
[project.entry-points."matplotlib.backend"]
inline = "matplotlib_inline.backend_inline"
Das interaktive Framework des Backends wird von seinem FigureCanvas.required_interactive_framework übernommen. Alle Einstiegspunkte werden zusammen geladen, aber erst bei Bedarf, z. B. wenn ein Backend-Name nicht als integriertes Backend erkannt wird oder wenn list_all() zum ersten Mal aufgerufen wird.