import numpy as np
import matplotlib.pyplot as plt
Allgemeines
In Python gibt es eine große Anzahl an Paketen, welche sich auf das Erstellen von Grafiken spezialisiert haben. Eine grafische Übersicht über dieses Ökosystem gibt es hier, die bekanntesten Pakete sind momentan:
Matplotlib ist das älteste und bekannteste Paket, es ist aber manchmal etwas umständlich zu bedienen – dafür ist es aber möglich, Grafiken bis ins kleinste Detail anzupassen. Außerdem basieren viele Grafikpakete auf Matplotlib, daher ist es jedenfalls hilfreich, wenn man zumindest ein grundlegendes Verständnis von Matplotlib besitzt.
Bokeh und Plotly können vor allem interaktive Grafiken für Webanwendungen erstellen. Seaborn und Vega-Altair haben sich auf statistische Grafiken spezialisiert. Seaborn baut auf Matplotlib auf und bietet sehr viele zusätzliche Grafiktypen. Vega-Altair hat sich das Ziel gesetzt, komplexe Grafiken möglichst einfach erstellen zu können. Auch interaktive Grafiken können damit erzeugt werden.
Neben diesen häufig verwendeten Paketen gibt es noch plotnine, welches sehr ähnlich wie ggplot2 für R zu verwenden ist.
Auf dieser und dieser Website kann man die Erstellung einiger typischer Grafiken mit den unterschiedlichen Paketen vergleichen.
Kurz zusammengefasst kann man also die Pakete Matplotlib, seaborn und plotnine zur Erzeugung von klassischen statischen Grafiken sowie Vega-Altair, Bokeh und Plotly zur Erstellung von interaktiven Grafiken empfehlen.
Matplotlib
Mit Matplotlib kann man verschiedenste Grafiken vor allem für wissenschaftliche Zwecke erstellen. Meist stehen die darzustellenden Daten als NumPy-Arrays zur Verfügung.
Die offizielle Matplotlib-Website beinhaltet einige Tutorials. Insbesondere die ersten beiden eignen sich sehr gut für den Einstieg und sind eine gute Ergänzung zu den Unterlagen dieser Einheit:
Wir beginnen wie immer mit den entsprechenden Import-Befehlen:
Beachten Sie, dass wir matplotlib.pyplot
(unter dem Namen plt
) importieren und nicht direkt matplotlib
. Dies hat historische Gründe, denn die allermeisten Funktionen zur Erstellung von Grafiken befinden sich in matplotlib.pyplot
.
In IPython sollte man zusätzlich folgenden Befehl ausführen, damit Grafikfenster sich unmittelbar öffnen und den Interpreter nicht blockieren:
%matplotlib
Im normalen interaktiven Python-Interpreter kann man direkt nach dem Importieren folgenden Befehl eingeben:
plt.ion()
Erstellung von Grafiken
Um mit Matplotlib Grafiken zu erzeugen, sollte man sich mit einigen Grundbegriffen sowie dem Aufbau einer Grafik vertraut machen, was in der folgenden Grafik veranschaulicht wird (modifiziert von hier):
Für den Anfang benötigen wir aber nur die zwei Begriffe Figure
und Axes
(in der Abbildung rot dargestellt): Eine Figure
entspricht einer Abbildung, welche eine oder mehrere Grafiken (sogenannte Axes
) enthalten kann.
Die Funktion plt.subplots
erzeugt eine Figure
und die gewünschte Anzahl an Axes
. Möchte man also z.B. eine Abbildung mit einer einzigen Grafik erzeugen, erstellt man diese leeren Objekte mit folgendem Befehl:
= plt.subplots() fig, ax
Die Funktion gibt die Figure
sowie die Axes
zurück; wir nennen diese fig
bzw. ax
. Danach kann man Methoden des Axes
-Objekts (welches wir ax
genannt haben) aufrufen, um die gewünschte Grafik zu erstellen (mehr dazu im nächsten Abschnitt).
Wenn man mehrere Grafiken in einer Abbildung kombinieren möchte, kann man mit plt.subplots
eine Figure
sowie die gewünschte Anzahl an Axes
erzeugen. Dazu verwendet man das erste bzw. die ersten beiden Argumente, welche der Anzahl an Zeilen bzw. Spalten, in denen die Grafiken angeordnet werden sollen, entsprechen:
= plt.subplots(1, 3) # 1 Zeile, 3 Spalten fig, axes
In diesem Beispiel erzeugen wir eine Figure
, welche drei Axes
beinhaltet, die in einer Zeile und drei Spalten angeordnet sind. In anderen Worten sind das also drei Grafiken, die nebeneinander dargestellt werden. Diese drei Axes
-Objekte haben wir axes
genannt, und dabei handelt es sich um ein eindimensionales NumPy-Array. Wir können daher auf die einzelnen Elemente mittels axes[0]
, axes[1]
und axes[2]
zugreifen und damit die gewünschten Grafiken erzeugen.
Auch eine echte zweidimensionale Anordnung, bestehend aus mehreren Zeilen und Spalten, ist so möglich. Zu beachten ist in diesem Fall aber, dass die zurückgegebenen Achsen in einem zweidimensionalen NumPy-Array vorhanden sind. Daher kann man die einzelnen Axes
-Objekte auch mit einem zweidimensionalen Index (also Zeile und Spalte) ansprechen, z.B. axes[0][2]
wäre das Axes
-Objekt in Zeile 0 (also erste Zeile) und Spalte 2 (also dritte Spalte).
Damit sich in einer Figure
mit mehreren Axes
-Objekten keine Überlappungen ergeben, sollten Sie zum Abschluss folgende Zeile hinzufügen:
True) fig.set_tight_layout(
Dies bewirkt, dass die Abstände zwischen den Axes
-Objekten so angepasst werden, dass keine Texte oder andere Elemente abgeschnitten werden oder überlappen.
Sehen wir uns die Auswirkung anhand eines Beispiels an. Zunächst erzeugen wir eine Grafik mit 2 Zeilen und 3 Spalten und verwenden das Standard-Layout:
= plt.subplots(2, 3) fig, axes
Und so sieht die Grafik mit optimiertem Layout aus:
= plt.subplots(2, 3)
fig, axes True) fig.set_tight_layout(
x/y-Grafiken
Matplotlib unterstützt viele unterschiedliche Grafiktypen. Als erstes sehen wir uns an, wie wir Liniengrafiken (z.B. zur Darstellung von Zeitverläufen) erstellen können. Dazu verwenden wir die folgenden Beispieldaten x
und y
:
= np.linspace(0, 10, 100)
x = np.sin(x) y
Eine Liniengrafik erhält man dann durch Aufruf der plot
-Methode, welcher man die Daten für die x- bzw. y-Achsen übergibt:
= plt.subplots()
fig, ax ax.plot(x, y)
Zur Erstellung eines Scatterplots verwendet man die Methode scatter
, welche sinnvolle Standardwerte für diesen Grafiktyp bietet:
= plt.subplots()
fig, ax ax.scatter(x, y)
Balken- und Stängelgrafiken
Für eine Balkengrafik benötigt man die Höhen der einzelnen Balken sowie die Positionen der Balken auf der x-Achse:
= np.arange(8)
x = [17, 5, 23, 33, 12, 21, 27, 18] y
Diese Werte kann man dann mit der bar
-Methode darstellen:
= plt.subplots()
fig, ax ax.bar(x, y)
Dieselben Werte könnte man auch als Stängelgrafik visualisieren:
= plt.subplots()
fig, ax ax.stem(x, y)
Histogramme
Auch statistische Grafiken können erzeugt werden. Dazu erstellen wir zunächst neue Beispieldaten x
(10000 normalverteilte Zufallszahlen mit Mittelwert 100 und Standardabweichung 15):
from numpy.random import default_rng
= default_rng(1)
rng = rng.normal(loc=100, scale=15, size=10000) x
Nun können wir die Verteilung von x
als Histogramm darstellen:
= plt.subplots()
fig, ax =50, edgecolor="white") ax.hist(x, bins
In diesem Beispiel haben wir die Anzahl der Bins manuell auf 50 gesetzt. Außerdem verwenden wir eine weiße Randfarbe, um die einzelnen Balken besser voneinander abzugrenzen.
Alle Methoden (also z.B. auch plot
, scatter
, bar
, stem
) haben optionale Argumente, mit denen man das Aussehen der Grafik anpassen kann. Diese sind in den jeweiligen Dokumentationen beschrieben.
Boxplots
Auch Boxplots dienen zur Visualisierung der Verteilung einer oder auch mehrerer Variablen. Erzeugen wir daher die folgenden drei Beispiel-Arrays:
= rng.normal(loc=0, scale=5, size=10000)
x = rng.exponential(5, size=10000)
y = rng.poisson(2.8, size=10000) z
Die Verteilungen der drei Variablen können wir mit drei Boxplots darstellen:
= plt.subplots()
fig, ax ax.boxplot([x, y, z])
Violinplots
Eine Alternative zu Boxplots sind sogenannte Violinplots. Die Daten aus dem vorigen Abschnitt könnte man also auch so darstellen:
= plt.subplots()
fig, ax ax.violinplot([x, y, z])
Weitere statistische Grafiken
Matplotlib bietet über die genannten statistischen Grafiktypen nicht mehr wesentlich mehr. Möchte man beispielsweise Scatterplots mit überlagerten Regressionsgeraden oder andere komplexere Grafiktypen erstellen, sollte man einen Blick auf andere Pakete wie seaborn oder plotnine werfen. Mit Matplotlib wäre das zwar prinzipiell auch möglich, aber es wären sehr viele manuelle Schritte notwendig (z.B. müsste man selbst ein lineares Regressionsmodell rechnen, um dieses dann in eine Grafik einzubinden).
Titel und Achsenbeschriftungen
Matplotlib fügt den Grafiken standardmäßig keine Titel oder Achsenbeschriftungen hinzu. Selbstverständlich kann man das aber anpassen, und zwar mit speziellen Methoden. Nehmen wir als Beispiel nochmals die allererste Grafik, die wir in diesen Unterlagen erzeugt haben:
= np.linspace(0, 10, 100)
x = np.sin(x)
y
= plt.subplots()
fig, ax ax.plot(x, y)
Wir können dieser Grafik einen Titel sowie Achsenbeschriftungen hinzufügen:
= plt.subplots()
fig, ax
ax.plot(x, y)"Eine Sinuskurve")
ax.set_title("Zeit (s)")
ax.set_xlabel("Amplitude (V)") ax.set_ylabel(
Alternativ könnte man statt den drei separaten Methoden auch folgende Variante verwenden:
= plt.subplots()
fig, ax
ax.plot(x, y)set(title="Eine Sinuskurve", xlabel="Zeit (s)", ylabel="Amplitude (V)") ax.
Übungen
Übung 1
Lesen Sie die Daten in der Datei airquality.csv
mit folgendem Code in ein NumPy-Array namens air
ein (beachten Sie, dass sich die Datei im Arbeitsverzeichnis befinden muss):
import numpy as np
= np.genfromtxt("airquality.csv", delimiter=",", skip_header=1) air
Dieser Datensatz den Verlauf von vier verschiedenen Luftgütewerten über einen Zeitraum von fünf Monaten.
Mit welchem Befehl können Sie die Anzahl der Zeilen und Spalten von air
herausfinden?
Übung 2
Die Spalten in air
beinhalten Messwerte für folgende Variablen:
- Ozonkonzentration (in ppb, oder “parts per billion”)
- Sonneneinstrahlung (in der Einheit Langleys)
- Windgeschwindigkeit (in Meilen pro Stunde)
- Temperatur (in Grad Fahrenheit)
- Monat (Zahlenwert zwischen 1 und 12)
- Tag (Zahlenwert zwischen 1 und 31)
Erstellen Sie für jede Spalte einen eigenen Namen (verwenden Sie die Namen ozone
, solar
, wind
, temp
, month
und day
). Verwenden Sie diese Namen in allen folgenden Übungen.
Übung 3
Erzeugen Sie mit Matplotlib ein Histogramm der Wind-Werte.
Übung 4
Erstellen Sie mit Matplotlib einen Scatterplot mit der Temperatur auf der x-Achse und dem Wind auf der y-Achse.
Übung 5
Stellen Sie folgende vier Grafiken in einer Abbildung dar (verwenden Sie dazu eine Anordung aus zwei Zeilen und zwei Spalten):
- Ein Scatterplot von
ozone
gegensolar
. - Eine Liniengrafik mit dem Verlauf von
temp
. - Ein Violinplot mit den Werten von
temp
für die fünf Monate. Die Werte für diese Monate entsprechen den folgenden Slices:temp[:31]
,temp[31:61]
,temp[61:92]
,temp[92:123]
,temp[123:]
. - Ein Scatterplot von
wind
gegenozone
.
Fügen Sie geeignete Achsenbeschriftungen hinzu und vergessen Sie nicht, zum Schluss fig.set_tight_layout(True)
aufzurufen!