Datenvisualisierung mit

Matplotlib

Um mit Matplotlib arbeiten zu können, muss die Bibliothek erst einmal importiert werden. Damit wir nicht so viel tippen müssen, geben wir ihr den kürzeren Namen plt.

In [1]:
from IPython.display import Image

import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = (10, 8)
plt.rcParams["font.size"] = 16
plt.rcParams["lines.linewidth"] = 2

Außerdem brauchen wir der Einfachheit halber ein paar Funktionen aus numpy, die dir schon bekannt vorkommen sollten.

In [2]:
import numpy as np

x = np.linspace(0, 1)  # gibt 50 Zahlen in gleichmäßigem Abstand von 0–1

Zu erst ein einfaches Beispiel mit $f(x)=x^2$. Um den Text-Output in diesem Notebook zu unterdrücken, schreiben wir manchmal ein ; hinter die letzte Zeile.

Im Folgenden verwenden wir die objekt-orientierte Schreibweise von matplotlib, die mehr Möglichkeiten und Freiheiten bietet. Diese rufst du mit

In [3]:
fig, ax = plt.subplots()

ax.plot(x, x**2);
No description has been provided for this image

auf. Du hast dann ein Objekt figure fig und ein Objekt axes ax, mit denen du interagieren und die Einstellungen im plot vornehmen kannst.

Das Objekt figure ist dabei die gesamte Abbildung, auf der sich Axen, labels und Text befinden können. Die einzelnen axes Objekte sind die jeweiligen Koordinatensysteme, in die man die entsprechenden Daten plottet. Mit diesen können auch Informationen über die Einheiten und Darstellung mit den Achsen definiert werden.

Anderes Beispiel: $\sin(t)$ mit verschiedenen Stilen. Vorsicht, die Funktionen und $\pi$ sind Bestandteil von numpy.

In [4]:
t = np.linspace(0, 2 * np.pi)

fig, ax = plt.subplots()
ax.plot(t, np.sin(t));
No description has been provided for this image
In [5]:
fig2, ax2 = plt.subplots()
ax2.plot(t, np.sin(t), "r--");
No description has been provided for this image
In [6]:
ax.cla()
ax.plot(t, np.sin(t), "go")
fig
Out[6]:
No description has been provided for this image

Tabelle mit einigen Farben und Stilen: matplotlib.axes.Axes.plot

Tabellen mit allen Farben und Stilen:

Der Vorteil ist nun, dass du z.B. mehrere Objekte fig und ax parallel benutzen und nachträglich wieder auf das vorherige zugreifen kannst.

Du kannst so auch im Nachhinein noch Dinge verändern und trotzdem die andere figure unverändert lassen.

In [7]:
fig
Out[7]:
No description has been provided for this image

Neue Grenzen mit set_xlim(a, b) und set_ylim(a, b)

In [8]:
ax.set_xlim(0, 2 * np.pi)
ax.set_ylim(-1.2, 1.2)
fig
Out[8]:
No description has been provided for this image
In [9]:
fig2
Out[9]:
No description has been provided for this image

Es fehlt noch etwas...

In [10]:
# https://imgs.xkcd.com/comics/convincing.png
Image(filename="images/xkcd-convincing.png")
Out[10]:
No description has been provided for this image
In [11]:
with plt.xkcd():
    fig, ax = plt.subplots()
    
    ax.set_title("Axes with labels")
    ax.plot(t, np.sin(t))
    ax.set_xlabel("t / s")
    ax.set_ylabel("U / V")
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlim(0, 2 * np.pi);
No description has been provided for this image

Einheiten in Achsenbeschriftungen werden wegdividiert:

Achsen-Beschriftungen können mit LaTeX-Code erstellt werden → LaTeX-Kurs in der nächsten Woche.

In [12]:
fig, ax = plt.subplots()

ax.plot(t, np.sin(t))
ax.set_xlabel(r"$t / \mathrm{s}$")
ax.set_ylabel(r"$U / \mathrm{V}$");

# ax.plot(t, np.sin(t))
# ax.set_xlabel(r'$t / \mathrm{s}$')
# ax.set_ylabel(r'$U \,/\, \mathrm{V}$');  # Spaces sind Geschmacksfrage
No description has been provided for this image

Mehr zu Einheiten gibt es im LaTeX-Kurs.

Als eine alternative Schreibweise für die verschiedenen settings der axes kann man auch

In [13]:
ax.set(
    xlim=(0, 2 * np.pi),
    xlabel=r"$t / \mathrm{s}$",
    ylabel=r"$U / \mathrm{V}$",
)
fig
Out[13]:
No description has been provided for this image

verwenden. Dabei können alle notwendigen Optionen der axes dann gebündelt hingeschrieben werden, was in der Übersichtlichkeit helfen kann.

Legende

Legenden für Objekte die ein label tragen

In [14]:
ax.plot(t, np.sin(t), label=r"$\sin(t)$")
ax.legend()
# ax.legend(loc="lower left")
# ax.legend(loc="best")
fig

# fig.legend()  # kann helfen, wenn man mehr als eine Achse und Platz für die Beschriftung an der Außenseite hat
# fig
Out[14]:
No description has been provided for this image

Seit matplotlib 2.0.2 ist loc=best standardmäßig eingestellt.

Andere möglche Orte für die Legende findest du in der Dokumentation.

Gitter

Mit grid() wird ein Gitter erstellt:

Hier wird auch der Vorteil der objekt-orientierten Schreibweise deutlich. Wir müssen keinen neuen plot erstellen, sondern können dem in fig hinterlegten neue Eigenschaften hinzufügen. Andere möglche Orte für die Legende findest du hier: https://matplotlib.org/api/legend_api.html.

In [15]:
ax.grid()
# ax.grid(visible=None)
fig

# Achtung: Unterschied ax.grid() und ax.grid(True) bei mehrfachem Ausführen.
# Nur in Notebooks relevant, da Zellen potentiell mehrfach ausgeführt werden.
# Doku: If visible is None and there are no kwargs, this toggles the visibility of the lines.
Out[15]:
No description has been provided for this image

Laden von Daten

In [16]:
x, y = np.genfromtxt("data/example_data_linear.txt", unpack=True)

fig, ax = plt.subplots()
ax.plot(x, y, "k.")

t = np.linspace(0, 10)
ax.plot(t, 5 * t, "r-");
No description has been provided for this image

Auslagern in ein Skript

Speicher den folgenden Code in eine Textdatei plot.py ab.

Öffne ein Terminal und starte das python-script mit:

python plot.py
In [17]:
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1)
fig, ax = plt.subplots()

ax.plot(x, x**2, "b-")
fig.savefig("plot.pdf")