Der Lebenszyklus eines Plots#

Dieses Tutorial soll den Anfang, die Mitte und das Ende einer einzelnen Visualisierung mit Matplotlib zeigen. Wir beginnen mit einigen Rohdaten und enden mit dem Speichern einer Abbildung einer angepassten Visualisierung. Unterwegs versuchen wir, einige interessante Funktionen und Best Practices mit Matplotlib hervorzuheben.

Hinweis

Dieses Tutorial basiert auf diesem ausgezeichneten Blogbeitrag von Chris Moffitt. Es wurde von Chris Holdgraf in dieses Tutorial umgewandelt.

Eine Anmerkung zu den expliziten vs. impliziten Schnittstellen#

Matplotlib hat zwei Schnittstellen. Eine Erklärung der Kompromisse zwischen der expliziten und der impliziten Schnittstelle finden Sie unter Matplotlib Application Interfaces (APIs).

In der expliziten objektorientierten (OO) Schnittstelle nutzen wir direkt Instanzen von axes.Axes, um die Visualisierung in einer Instanz von figure.Figure aufzubauen. In der impliziten Schnittstelle, inspiriert und modelliert nach MATLAB, verwenden wir eine auf globalem Zustand basierende Schnittstelle, die im Modul pyplot gekapselt ist, um auf die „aktuelle Achse“ zu zeichnen. Sehen Sie sich die pyplot-Tutorials für einen detaillierteren Einblick in die pyplot-Schnittstelle an.

Die meisten Begriffe sind selbsterklärend, aber das Wichtigste ist, sich daran zu erinnern, dass

  • Die Figure das endgültige Bild ist und ein oder mehrere Axes enthalten kann.

  • Die Axes stellt eine einzelne Grafik dar (nicht zu verwechseln mit

    Axis, was sich auf die x-, y- oder z-Achse einer Grafik bezieht).

Wir rufen Methoden, die das Plotten durchführen, direkt von den Axes auf, was uns viel mehr Flexibilität und Leistung bei der Anpassung unserer Grafik bietet.

Hinweis

Verwenden Sie im Allgemeinen die explizite Schnittstelle gegenüber der impliziten pyplot-Schnittstelle zum Plotten.

Unsere Daten#

Wir verwenden die Daten aus dem Beitrag, aus dem dieses Tutorial abgeleitet wurde. Es enthält Verkaufsinformationen für eine Reihe von Unternehmen.

import matplotlib.pyplot as plt
import numpy as np

data = {'Barton LLC': 109438.50,
        'Frami, Hills and Schmidt': 103569.59,
        'Fritsch, Russel and Anderson': 112214.71,
        'Jerde-Hilpert': 112591.43,
        'Keeling LLC': 100934.30,
        'Koepp Ltd': 103660.54,
        'Kulas Inc': 137351.96,
        'Trantow-Barrows': 123381.38,
        'White-Trantow': 135841.99,
        'Will LLC': 104437.60}
group_data = list(data.values())
group_names = list(data.keys())
group_mean = np.mean(group_data)

Erste Schritte#

Diese Daten werden natürlich als Balkendiagramm visualisiert, mit einem Balken pro Gruppe. Um dies mit dem objektorientierten Ansatz zu tun, generieren wir zuerst eine Instanz von figure.Figure und axes.Axes. Die Figure ist wie eine Leinwand, und die Axes ist ein Teil dieser Leinwand, auf der wir eine bestimmte Visualisierung erstellen werden.

Hinweis

Figures können mehrere Axes darauf haben. Informationen, wie dies geschieht, finden Sie im Tutorial Tight Layout Tutorial.

lifecycle

Nachdem wir nun eine Axes-Instanz haben, können wir darauf plotten.

lifecycle

Steuerung des Stils#

Es gibt viele Stile, die in Matplotlib verfügbar sind, um Ihre Visualisierung an Ihre Bedürfnisse anzupassen. Um eine Liste der Stile zu sehen, können wir style verwenden.

['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'petroff10', 'seaborn-v0_8', 'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook', 'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']

Sie können einen Stil mit folgendem aktivieren

plt.style.use('fivethirtyeight')

Lassen Sie uns nun die obige Grafik neu erstellen, um zu sehen, wie sie aussieht

lifecycle

Der Stil steuert viele Dinge, wie Farben, Linienstärken, Hintergründe usw.

Anpassung der Grafik#

Nun haben wir eine Grafik mit dem gewünschten allgemeinen Aussehen, also verfeinern wir sie, damit sie druckreif ist. Zuerst drehen wir die Beschriftungen auf der x-Achse, damit sie deutlicher angezeigt werden. Wir können auf diese Beschriftungen mit der Methode axes.Axes.get_xticklabels() zugreifen.

lifecycle

Wenn wir die Eigenschaften vieler Elemente auf einmal festlegen möchten, ist es nützlich, die Funktion pyplot.setp() zu verwenden. Diese nimmt eine Liste (oder viele Listen) von Matplotlib-Objekten und versucht, ein Stilelement von jedem einzelnen festzulegen.

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
lifecycle

Es sieht so aus, als wären einige der Beschriftungen unten abgeschnitten. Wir können Matplotlib anweisen, automatisch Platz für Elemente in den von uns erstellten Figuren zu schaffen. Dazu setzen wir den Wert autolayout unserer rcParams. Weitere Informationen zur Steuerung von Stil, Layout und anderen Funktionen von Grafiken mit rcParams finden Sie unter Matplotlib mit Stilvorlagen und rcParams anpassen.

plt.rcParams.update({'figure.autolayout': True})

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
lifecycle

Als Nächstes fügen wir der Grafik Beschriftungen hinzu. Um dies mit der OO-Schnittstelle zu tun, können wir die Methode Artist.set() verwenden, um Eigenschaften dieses Axes-Objekts festzulegen.

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
Company Revenue

Wir können auch die Größe dieser Grafik mit der Funktion pyplot.subplots() anpassen. Dies können wir mit dem Schlüsselwortargument figsize tun.

Hinweis

Während die Indizierung in NumPy der Form (Zeile, Spalte) folgt, folgt das Schlüsselwortargument figsize der Form (Breite, Höhe). Dies folgt den Konventionen in der Visualisierung, die leider von denen der linearen Algebra abweichen.

fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
Company Revenue

Für Beschriftungen können wir benutzerdefinierte Formatierungsrichtlinien in Form von Funktionen angeben. Unten definieren wir eine Funktion, die eine Ganzzahl als Eingabe nimmt und eine Zeichenkette als Ausgabe zurückgibt. Wenn sie mit Axis.set_major_formatter oder Axis.set_minor_formatter verwendet wird, erstellt und verwendet sie automatisch eine Klasse ticker.FuncFormatter.

Bei dieser Funktion ist das Argument x die ursprüngliche Tick-Beschriftung und pos ist die Tick-Position. Wir werden hier nur x verwenden, aber beide Argumente sind erforderlich.

def currency(x, pos):
    """The two arguments are the value and tick position"""
    if x >= 1e6:
        s = f'${x*1e-6:1.1f}M'
    else:
        s = f'${x*1e-3:1.0f}K'
    return s

Wir können diese Funktion dann auf die Beschriftungen unserer Grafik anwenden. Dazu verwenden wir das Attribut xaxis unserer Axes. Dies ermöglicht es Ihnen, Aktionen auf einer bestimmten Achse unserer Grafik durchzuführen.

fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
Company Revenue

Kombination mehrerer Visualisierungen#

Es ist möglich, mehrere Plot-Elemente auf derselben Instanz von axes.Axes zu zeichnen. Dazu müssen wir einfach eine weitere der Plot-Methoden auf diesem Axes-Objekt aufrufen.

fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')

# Annotate new companies
for group in [3, 5, 8]:
    ax.text(145000, group, "New Company", fontsize=10,
            verticalalignment="center")

# Now we move our title up since it's getting a little cramped
ax.title.set(y=1.05)

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)

plt.show()
Company Revenue

Speichern unserer Grafik#

Nachdem wir nun mit dem Ergebnis unserer Grafik zufrieden sind, möchten wir sie auf der Festplatte speichern. Es gibt viele Dateiformate, in die wir in Matplotlib speichern können. Um eine Liste der verfügbaren Optionen zu sehen, verwenden Sie

{'eps': 'Encapsulated Postscript', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'ps': 'Postscript', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format', 'webp': 'WebP Image Format'}

Wir können dann figure.Figure.savefig() verwenden, um die Grafik auf der Festplatte zu speichern. Beachten Sie, dass es mehrere nützliche Flags gibt, die wir unten zeigen

  • transparent=True macht den Hintergrund der gespeicherten Grafik transparent, wenn das Format dies unterstützt.

  • dpi=80 steuert die Auflösung (Punkte pro Zoll) der Ausgabe.

  • bbox_inches="tight" passt die Grenzen der Grafik an unsere Darstellung an.

# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")

Gesamtlaufzeit des Skripts: (0 Minuten 3,734 Sekunden)

Galerie generiert von Sphinx-Gallery