Funktionales Interface#

Mit der “funktionalen” Bedinung von Matplotlib kann man relativ schnell relativ einfache Diagramme erstellen. Hat man Matplotlib bzw. Pyplot mit import matplotlib.pyplot as plt importiert, dann kann man z.B. ein simples Liniendiagramm mit der Funktion plt.plot() erstellen. Im Folgenden schauen wir uns v.a. die Erstellung von Liniendiagrammen an, wir werden aber im Verlauf des Kurses noch andere Diagrammtypen kennenlernen.

Liniendiagramme mit plt.plot()#

Die Funktion plt.plot() erwartet mindestens eine Datenreihe, also z.B. eine Liste mit Zahlen, um die Linie zeichnen zu können. Unten im Beispiel erstelle ich zunächst die Liste infections, welche (fiktive) Daten über eine ansteckende Krankheit deiner Wahl enthält. Diese Datenreihe - die Liste infections - stecke ich als Input in die Funktion plt.plot() und schon wird ein Liniendiagramm angezeigt.

import matplotlib.pyplot as plt

infections = [1, 2, 3, 5, 8, 13, 21, 34, 55]

plt.plot(infections)
[<matplotlib.lines.Line2D at 0x2458085e388>]
../_images/amp06a_02_funktionales_matplotlib_1_1.png

Das ging einfach. Allerdings ist es, je nach Programmierumgebung oder auch je nach Einstellungen in Spyder, möglicherweise notwendig, nach der Anwendung der Funktion plt.plot() noch die Funktion plt.show() anzuwenden, damit das Diagramm auch tatsächlich angezeigt wird. Man kann sich vorstellen, dass durch die Funktion plt.plot() das Diagramm bereits “verdeckt” gezeichnet wird, aber noch nicht unbedingt direkt angezeigt wird, weil Python abwartet, ob man nicht vielleicht noch mehr in das Diagramm einzeichnen möchte. Damit der Code immer reproduziert werden kann bzw. die Grafiken auch tatsächlich angezeigt werden, sollte man sich angewöhnen, die Funktion plt.show() so oder so immer zu verwenden. Der Code sieht dann insgesamt so aus, das Diagramm sieht aber noch exakt gleich aus:

plt.plot(infections)
plt.show()
../_images/amp06a_02_funktionales_matplotlib_3_0.png

Ein Liniendiagramm gehört klassischerweise zu den zweidimensionalen Diagrammen. D.h. die Position eines Datenpunktes im Diagramm bestimmt sich durch einen Wert auf der X-Achse und einem Wert auf der Y-Achse - wie in einem “Koordinaten-System”. Wir haben der Funktion plt.plot() aber nur eine Datenreihe und somit nur Informationen über eine Dimension d.h. eine Achse gegeben. Bevor du weiterliest: Schaue dir doch mal das Diagramm an und überlege, für welche der beiden Achsen die eingegebene Datenreihe verwendet wurde.

Bei der Eingabe von genau einer Datenreihe verwendet die Funktion plt.plot() die darin enthaltenen Daten als Positionen auf der Y-Achse. Die X-Achse hingegen ergibt sich einfach aus der Position der Zahl in der Datenreihe, in diesem Fall also aus den Positionen von 0 bis 8. Möchte man hingegen selbst Daten für die Werte der X-Achse verwenden, dann kann man eine zweite Datenreihe mit derselben Länge wie die erste Datenreihe eingeben.

Wichtig ist nun allerdings, dass die Datenreihe, welche die X-Positionen angeben, an erster Stelle und die Datenreihe, welche die Y-Positionen angeben, an zweiter Stelle in die Funktion plt.plot() eingegeben werden. Im Falle von zwei eingegebenen Datenreihen sieht die allgemeine Syntax somit also so aus: plt.plot(XDATA, YDATA). Gibt man hingegen nur eine Datenreihe ein, dann sieht die allgemeine Syntax so aus: plt.plot(YDATA).

Im Folgenden definiere ich zusätzlich zur Liste infections noch die Liste days und gebe sie mit in die Funktion plt.plot() ein, um die Anzahl der Infektionen an bestimmten Tagen darzustellen. Wichtig ist, dass beide Datenreihen gleich lang sind!

infections = [1, 2, 3, 5, 8, 13, 21, 34, 55]
days = [1, 5, 7, 9, 15, 19, 25, 26, 29]

plt.plot(days, infections)
plt.show()
../_images/amp06a_02_funktionales_matplotlib_5_0.png

Mehr als eine Linie#

Möchte man mehr als eine Linie in dasselbe Diagramm einzeichnen, dann kann man die Funktion plt.plot() einfach mehrmals hintereinander mit unterschiedlichen Daten ausführen.

Unten erstelle ich zunächst zwei mal zwei Datenreihen namens density_data_1 und speed_data_1 sowie density_data_2 und speed_data_2. Dann führe ich zwei mal hintereinander die Funktion plt.plot() mit den jeweiligen X- und Y-Datenreihen aus und rufe dann schließlich die Funktion plt.show() auf.

Zur Info

Die Daten entstammen einem Simulationsexperiment auf Basis des Nasch-Modells, wobei untersucht wird, inwiefern die Verkehrsdichte auf einer Straße auf die durchschnittlich gefahrene Geschwindigkeit wirkt. Die Wahrscheinlichkeit des zufälligen Abbremsens (Trödelwahrscheinlichkeit) war bei der Generierung der Datenreihen density_data_1 und speed_data_1 auf 0, bei density_data_2 und speed_data_2 hingegen auf 0.3 eingestellt. Dadurch kann eine Moderation des Zusammenhangs zwischen der Verkehrsdichte und der durchschnittlichen Geschwindigkeit untersucht werden.

In der Forschungspraxis kommt es natürlich selten vor, dass man die Datenreihen selbst per Hand als Code eingibt, so wie ich es hier tue. Stattdessen produziert man solche Daten natürlich durch das automatisierte Ausführen der Modelle und der direkten Speicherung der Ergebnisse als Datensatz bzw. in einem Datencontainer wie z.B. einer Liste.

# Daten für erste Linie
density_data_1 = [1.0, 0.5, 0.33, 0.25, 0.2, 0.17, 0.14, 0.12, 0.11, 0.1, 0.09, 0.08, 0.07, 0.06, 0.05, 0.05]
speed_data_1 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]


# Daten für zweite Linie
density_data_2 = [1.0, 0.5, 0.33, 0.25, 0.2, 0.17, 0.14, 0.12, 0.11, 0.1, 0.09, 0.08, 0.07, 0.06, 0.06, 0.06, 0.05]
speed_data_2 = [0.0, 0.59, 1.15, 1.68, 2.24, 2.75, 3.32, 3.74, 4.24, 4.64, 4.66, 4.67, 4.68, 4.68, 4.69, 4.69, 4.69]

# Daten plotten
plt.plot(density_data_1, speed_data_1) # erste Linie zeichnen
plt.plot(density_data_2, speed_data_2) # zweite Linie zeichnen
plt.show()
../_images/amp06a_02_funktionales_matplotlib_8_0.png

Beim obigen Beispiel ist es besonders wichtig, die Funktion plt.show() wirklich erst dann aufzurufen, nachdem man alles in das Diagramm eingezeichnet hat. Denn nachdem die erste Anwendung von plt.plot() ein neues Diagramm intern erstellt, zeichnen alle darauffolgenden Anwendungen von plt.plot() ihre Linien (oder auch Punkte) in dieses Diagramm - solange bis die Funktion plt.show() ausgeführt wird. Durch plt.show() wird der “Bearbeitungsmodus” des aktuellen Diagramms beendet. Ein nun folgender Aufruf der Funktion plt.plot() erstellt wieder ein neues Diagramm, in das dann wieder solange alle danach folgenden Aufrufe von plt.plot ihre Graphen malen bis die Funktion plt.show() aufgerufen wird.

Das Diagramm aufhübschen#

Achsen beschriften#

Zu einem richtigen Diagramm gehören vernünftige Beschriftungen. Mit den Funktionen plt.xlabel() und plt.ylabel() kann man die X- und Y-Achse beschriften, wie ich unten im Beispiel zeige:

plt.plot(density_data_1, speed_data_1) # erste Linie zeichnen
plt.plot(density_data_2, speed_data_2) # zweite Linie zeichnen
plt.xlabel("Verkehrsdichte") # X-Achse beschriften
plt.ylabel("Durchschnittliche Geschwindigkeit") # Y-Achse beschriften
plt.show()
../_images/amp06a_02_funktionales_matplotlib_11_0.png

Legende einfügen#

Hat man mehr als eine Linie im Diagramm, dann macht es Sinn auch die Linien innerhalb einer Legende zu beschriften. Dies erreicht man, indem man beim Aufruf der Funktion plt.plot() zusätzlich dem Argument label eine jeweilige Beschriftung für die zuweist, so wie ich es unten tue. Um dann auch wirklich innerhalb des Plots die Legende anzeigen zu lassen, muss man zusätzlich noch die Funktion plt.legend() aufrufen.

plt.plot(density_data_1, speed_data_1, label="Ohne Trödeln") # erste Linie zeichnen und beschriften
plt.plot(density_data_2, speed_data_2, label="Mit Trödeln") # zweite Linie zeichnen und beschriften
plt.xlabel("Verkehrsdichte") # X-Achse beschriften
plt.ylabel("Durchschnittliche Geschwindigkeit") # Y-Achse beschriften
plt.legend() # Legende anzeigen lassen
plt.show()
../_images/amp06a_02_funktionales_matplotlib_13_0.png

Gitter einfügen#

Möchte man zur besseren Lesbarkeit des Diagramms ein Gitter in den Hintergrund einzeichnen, dann kann man das durch den Aufruf der Funktion plt.grid() tun.

plt.plot(density_data_1, speed_data_1, label="Ohne Trödeln") # erste Linie zeichnen und beschriften
plt.plot(density_data_2, speed_data_2, label="Mit Trödeln") # zweite Linie zeichnen und beschriften
plt.xlabel("Verkehrsdichte") # X-Achse beschriften
plt.ylabel("Durchschnittliche Geschwindigkeit") # Y-Achse beschriften
plt.legend() # Legende anzeigen lassen
plt.grid() # Gitter anzeigen lassen
plt.show()
../_images/amp06a_02_funktionales_matplotlib_15_0.png

Alternative Styles#

Gefällt einem der standardmäßig eingestellte Farbstil von Matplotlib nicht, dann kann man mit dem Befehl plt.style.use() einen anderen Style aussuchen. Dabei muss man den Namen eines anderen Stils wissen und als Argument in die Funktion plt.style.use() eingeben. Eine Auswahl an verfügbaren Stilen findest du z.B. hier. Unten rufe ich die plt.style.use() und gebe den Style "ggplot" als Argument ein:

plt.style.use("ggplot")

Alle ab jetzt erstellten Diagramme werden in dem oben eingestellten Stil erstellt. ACHTUNG: Bei manchen Stilen, wie z.B. dem Stil "ggplot" ist das Gitter bereits voreingestellt. Ein erneutes Aufrufen der Funktion plt.grid() würde das Gitter tatsächlich wieder verschwinden lassen. Daher rufe ich unten nicht die Funktion plt.grid() auf.

plt.plot(density_data_1, speed_data_1, label="Ohne Trödeln") # erste Linie zeichnen und beschriften
plt.plot(density_data_2, speed_data_2, label="Mit Trödeln") # zweite Linie zeichnen und beschriften
plt.xlabel("Verkehrsdichte") # X-Achse beschriften
plt.ylabel("Durchschnittliche Geschwindigkeit") # Y-Achse beschriften
plt.legend() # Legende anzeigen lassen
plt.show()
../_images/amp06a_02_funktionales_matplotlib_19_0.png

Mittels For-Loop zeichnen#

Wenn man viele Linen zu zeichnen hat, dann kann man das ganze auch beispielsweise mit einem For-Loop automatisieren. Hier ein Beispiel, bei dem ich die drei Y-Datenreihen y1, y2 und y3 gesammelt in der Liste data vorliegen habe und diese nacheinander per For-Loop in dasselbe Diagramm einzeichne. Hier ist es besonders wichtig, die Funktion plt.show() erst nach dem For-Loop aufzurufen!

Im Rahmen von ABM kann das z.B. vorkommen, wenn man eine Liste von Agenten vorliegen hat und für jeden Agenten z.B. dessen als Agenten-Attribut vorliegende Meinungsveränderung über mehrere Zeitschritte in ein Diagramm einzeichnen möchte.

y1 = [10, 9, 8, 9, 8, 7, 6, 5, 5, 6]
y2 = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
y3 = [0, 0, 0, 1, 2, 3, 3, 3, 3, 4]

data = [y1, y2, y3]

for y_data in data:
    plt.plot(y_data)
plt.show()
../_images/amp06a_02_funktionales_matplotlib_21_0.png