Performance#

Ob Sie Daten im interaktiven Modus erkunden oder programmatisch viele Plots speichern, die Rendering-Performance kann ein herausfordernder Engpass in Ihrer Pipeline sein. Matplotlib bietet mehrere Möglichkeiten, die Rendering-Zeit bei geringfügigen Änderungen (auf eine einstellbare Toleranz) am Erscheinungsbild Ihres Plots erheblich zu reduzieren. Die verfügbaren Methoden zur Reduzierung der Rendering-Zeit hängen vom Typ des erstellten Plots ab.

Vereinfachung von Liniensegmenten#

Für Plots, die Liniensegmente enthalten (z. B. typische Liniendiagramme, Umrisse von Polygonen usw.), kann die Rendering-Performance durch rcParams["path.simplify"] (Standard: True) und rcParams["path.simplify_threshold"] (Standard: 0.111111111111) gesteuert werden, die z. B. in der matplotlibrc-Datei definiert werden können (siehe Anpassen von Matplotlib mit Stylesheets und rcParams für weitere Informationen zur matplotlibrc-Datei). rcParams["path.simplify"] (Standard: True) ist ein boolescher Wert, der angibt, ob Liniensegmente überhaupt vereinfacht werden. rcParams["path.simplify_threshold"] (Standard: 0.111111111111) steuert, wie stark Liniensegmente vereinfacht werden; höhere Schwellenwerte führen zu schnellerem Rendering.

Das folgende Skript zeigt zuerst die Daten ohne jegliche Vereinfachung und dann dieselben Daten mit Vereinfachung an. Versuchen Sie, mit beiden zu interagieren.

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

# Setup, and create the data to plot
y = np.random.rand(100000)
y[50000:] *= 2
y[np.geomspace(10, 50000, 400).astype(int)] = -1
mpl.rcParams['path.simplify'] = True

mpl.rcParams['path.simplify_threshold'] = 0.0
plt.plot(y)
plt.show()

mpl.rcParams['path.simplify_threshold'] = 1.0
plt.plot(y)
plt.show()

Matplotlib verwendet standardmäßig einen konservativen Vereinfachungsschwellenwert von 1/9. Um die Standardeinstellungen zu ändern und einen anderen Wert zu verwenden, ändern Sie die matplotlibrc-Datei. Alternativ können Benutzer einen neuen Stil für die interaktive Darstellung (mit maximaler Vereinfachung) und einen anderen Stil für die Darstellung in Publikationsqualität (mit minimaler Vereinfachung) erstellen und diese nach Bedarf aktivieren. Siehe Anpassen von Matplotlib mit Stylesheets und rcParams für Anweisungen, wie Sie diese Aktionen durchführen.

Die Vereinfachung funktioniert durch iteratives Zusammenführen von Liniensegmenten zu einem einzigen Vektor, bis der senkrechte Abstand des nächsten Liniensegments zum Vektor (gemessen im Anzeigekoordinatenraum) größer ist als der Parameter path.simplify_threshold.

Hinweis

Änderungen an der Art und Weise, wie Liniensegmente vereinfacht werden, wurden in Version 2.1 vorgenommen. Die Rendering-Zeit wird durch diese Parameter auch vor Version 2.1 verbessert, aber die Rendering-Zeit für einige Arten von Daten wird in Version 2.1 und höher drastisch verbessert.

Marker-Teilabtastung#

Marker können ebenfalls vereinfacht werden, wenn auch weniger robust als Liniensegmente. Die Marker-Teilabtastung ist nur für Line2D-Objekte verfügbar (über die Eigenschaft markevery). Überall dort, wo Line2D-Konstruktorparameter übergeben werden, wie z. B. bei pyplot.plot und Axes.plot, kann der Parameter markevery verwendet werden.

plt.plot(x, y, markevery=10)

Das Argument markevery ermöglicht eine einfache Teilabtastung oder einen Versuch, gleichmäßig verteilte (entlang der x-Achse) Stichproben zu nehmen. Weitere Informationen finden Sie in der Markevery Demo.

Aufteilen von Linien in kleinere Abschnitte#

Wenn Sie das Agg-Backend verwenden (siehe Was ist ein Backend?), können Sie rcParams["agg.path.chunksize"] (Standard: 0) verwenden. Dies ermöglicht es Benutzern, eine Chunk-Größe anzugeben, und alle Linien mit mehr als dieser Anzahl von Eckpunkten werden in mehrere Linien aufgeteilt, von denen jede nicht mehr als agg.path.chunksize Eckpunkte hat. (Es sei denn, agg.path.chunksize ist null, in diesem Fall erfolgt keine Aufteilung.) Für einige Datentypen kann das Aufteilen der Linie in sinnvolle Größen die Rendering-Zeit erheblich reduzieren.

Das folgende Skript zeigt zuerst die Daten ohne Beschränkung der Chunk-Größe und dann dieselben Daten mit einer Chunk-Größe von 10.000 an. Der Unterschied ist am besten zu sehen, wenn die Abbildungen groß sind. Versuchen Sie, die GUI zu maximieren und dann mit ihnen zu interagieren.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['path.simplify_threshold'] = 1.0

# Setup, and create the data to plot
y = np.random.rand(100000)
y[50000:] *= 2
y[np.geomspace(10, 50000, 400).astype(int)] = -1
mpl.rcParams['path.simplify'] = True

mpl.rcParams['agg.path.chunksize'] = 0
plt.plot(y)
plt.show()

mpl.rcParams['agg.path.chunksize'] = 10000
plt.plot(y)
plt.show()

Legenden#

Das Standardverhalten der Legende für Achsen versucht, den Ort zu finden, der die wenigsten Datenpunkte abdeckt (loc='best'). Dies kann eine sehr teure Berechnung sein, wenn viele Datenpunkte vorhanden sind. In diesem Fall möchten Sie möglicherweise einen bestimmten Ort angeben.

Verwenden des *fast*-Stils#

Der *fast*-Stil kann verwendet werden, um Vereinfachungs- und Chunking-Parameter automatisch auf vernünftige Einstellungen zu setzen, um das Plotten großer Datenmengen zu beschleunigen. Der folgende Code führt ihn aus.

import matplotlib.style as mplstyle
mplstyle.use('fast')

Er ist sehr leichtgewichtig, sodass er gut mit anderen Stilen funktioniert. Stellen Sie sicher, dass der *fast*-Stil zuletzt angewendet wird, damit andere Stile die Einstellungen nicht überschreiben.

mplstyle.use(['dark_background', 'ggplot', 'fast'])