Die Matplotlib unterstützt dich dabei, statistische Daten zu visualisieren. Für diesen Tutorialteil ist etwas Basiswissen in Statistik hilfreich.

Matplotlib installieren
Da die Matplotlib gut zu Numpy passt, kannst du die virtuelle Umgebung aus dem letzten Tutorialteil gut wiederverwenden und musst die Bibliothek nur mit
pip install matplotlib
darin installieren.
Per Konvention wird in allen Python Programmen diese Library wie folgt importiert:
import matplotlib as plt
Von solchen Konventionen solltest du nur in gut begründeten Ausnahmefällen abweichen und dies entsprechend dokumentieren.
Für die Beispiele hier benötigst du ein Raspberry Pi OS mit Desktopinstallation, da wir hier Grafiken erzeugen und anzeigen.
Ich möchte hier keine Dummydaten verwenden sondern echte Statistikdaten aus dem OpenData Portal der Stadt Wuppertal. Dazu ziehe ich die CSV-Datei mit den Vornamen, die den im Jahr 2020 Geborenen gegeben wurden. Diese Daten sind unter CC-BY 4.0 Stadt Wuppertal offenedaten-wuppertal.de lizenziert.
Du kannst sie mit
wget https://www.offenedaten-wuppertal.de/sites/default/files/Vornamen_Wuppertal_2020.csv
frei herunterladen. Um damit herumzuspielen, benötigen wir zunächst eine Methode, um sie zu laden. Diese ist in einem eigenen .py File untergebracht, um sie per import wiederzuverwenden.
vornamen_reader.py
#encoding: utf-8
def read_vornamen(filename):
dict = {}
# Der Zähler dient nur dazu, die erste Zeile zu überspringen
count = 0
dict['mädchen'] = 0
dict['jungs'] = 0
dict['divers'] = 0
with open(filename,'r') as f:
for zeile in f:
if count >0:
# einzelne Zeile in seine Bestandteile zerlegen
splitted = zeile.strip().split(';')
anzahl = splitted[0]
vorname = splitted[1]
geschlecht= splitted[2]
position = splitted[3]
if geschlecht == 'w':
dict['mädchen'] += 1
elif geschlecht == 'm':
dict['jungs'] += 1
else:
dict['divers'] += 1
data = {}
data['vorname'] = vorname
data['anzahl'] = int(anzahl)
data['geschlecht'] = geschlecht
data['position'] = position
if vorname not in dict:
dict[vorname] = data
else:
# doppelte Einträge summieren wir auf.
e = dict[vorname]
e['anzahl'] = int(anzahl) + (e['anzahl'])
count +=1
gesamt = dict['jungs'] + dict['mädchen'] + dict['divers']
dict['gesamt'] = gesamt
return dict
Die Methode liefert und ein Dictionary mit den Vornamen als Schlüssel und einem Unter-Dictionary mit den Werten wie anzahl
, geschlecht
und position
des Vornamens. Die Position brauchen wir eigentlich nicht, wir nehmen sie trotzdem einfach mit. Außerdem enthält das Haupt-Dictionary noch ein paar Metadaten, mit der Anzahl von Jungen, Mädchen und divers. Das diverse Geschlecht spielt bei der Geburt eigentlich keine Rolle, wir werten es später trotzdem aus.
Wir können die Daten jetzt laden, lass uns jetzt mal sehen, welche Möglichkeiten uns die Matplotlib bietet, diese als Grafik darzustellen.
Säulendiagramm
Ein Säulendiagramm ist gut geeignet, um einige absolute Werte darzustellen. Du kannst es bei jeder Wahl sehen, wenn es um die Stimmenanzahl geht. Meistens sind die verschiedenen Balken unterschiedlich eingefärbt.
Wir wollen hier die Anzahl der verschiedenen Geschlechter darstellen. D.h., wir benötigen drei Balken, jeweils einen für weiblich, männlich und divers. Diese sollen die Farben rot, blau und grün haben.
vornamen_saeulen.py
#encoding: utf-8
import matplotlib.pyplot as plt
from vornamen_reader import read_vornamen
def plot_geschlecht(vornamen):
bez= ['Mädchen', 'Jungs','divers']
geburten = [vornamen['mädchen'], vornamen['jungs'],vornamen['divers']]
print(f'geburten={geburten}')
farben = ['red','blue','green']
fig, ax = plt.subplots()
ax.bar(bez,geburten,label=bez, color=farben)
ax.set_ylabel('Geburten')
ax.set_title('Geburten nach Geschlecht Wuppertal 2020')
ax.legend(title='Geburten')
plt.show()
if __name__ == '__main__':
vornamen = read_vornamen('./Vornamen_Wuppertal_2020.csv')
jungs= vornamen['jungs']
maedels = vornamen['mädchen']
divers = vornamen['divers']
print(f'Jungs: {jungs}')
print(f'Mädchen: {maedels}')
print(f'divers: {divers}')
# print(f'vornamen={vornamen}')
plot_geschlecht(vornamen)
Die Methode plot_geschlecht
() erhält als Parameter unser Dictionary mit den geladenen Daten. Dann definiert sie einige Listen mit Parametern, die wir an die Matplotlib weitergeben. Dazu gehören die absoluten Werte für die Anzahl Geburten pro Geschlecht in geburten
. In bez
definieren wir die Bezeichnungen der Balken, in farben
die Farben. Die Reihenfolge muss in den Arrays immer gleich sein, so ist das Element 0
für die Anzahl der Geburten von Mädchen vorgesehen, der Balken trägt das Label „Mädchen“ und wird in rot (red) dargestellt. Die Säule für „divers“ würde in grün angezeigt werden, sofern der Wget größer als 0
wäre.
Nachdem diese Parameter alle definiert sind, lassen wir uns über die Methode plt.subplots()
den grafischen Kontext für unser Diagramm erzeugen. Die Methode liefert zwei Objekte zurück: fig
enthält ein Figure-Objekt, dass wir nicht benötigen, in ax
steckt die Definition der Achsen unseres Diagramms. Dort werden unsere oben definierten Listen später verarbeitet. Die Beschriftung der Y-Achse setzen wir mit ax.set_ylabel('Geburten')
und die Überschrift des Diagramms mit ax.set_title('Geburten nach Geschlecht Wuppertal 2020')
. Es ist nie falsch, eine Legende zur Erklärung einzublenden. Diese kann eine eigene Überschrift haben, die mit ax.legend(title='Geburten')
übergeben wird.
Jetzt hast du alle notwendigen Werte für das Diagramm gesetzt und kannst es mit plt.show()
anzeigen.

gestapeltes Säulendiagramm
Ein gestapeltes Säulendiagramm erlaubt es dir, mehr als nur einen Wert pro Säule zu präsentieren, in diesem Beispiel die fiktiven Verkäufe mehrerer Obstsorten pro Jahr.
#! ./bin/python
#encoding: utf-8
import matplotlib.pyplot as plt
import numpy as np
jahre= np.array(['2018','2019', '2020'])
aepfel= np.array([1000,1500,2000])
erdbeeren =np.array([500,950,900])
bananen=np.array([400,800,750])
breite = 0.6
fig,ax = plt.subplots()
#ax.legend('Verkäufe')
ax.bar(jahre,bananen,color='yellow')
ax.bar(jahre,erdbeeren,bottom=bananen,color='red')
ax.bar(jahre,aepfel,bottom=erdbeeren,color='green')
plt.legend(['Bananen','Erdbeeren','Äpfel'])
plt.show()
Die Vorgehensweise ist ähnlich dem einfachen Säulendiagramm, du definierst halt statt einem Array mit Werten mehrere (aepfel, erdbeeren
und bananen
) . Statt einem Aufruf von ax.bar()
hast du jetzt drei, bei denen du über den bottom
Parameter die Reihenfolge des Stapels festlegen kannst.

Balkendiagramm

Funktions-Graphen
Mit Graphen zu Funktionen haben wir uns alle früher mal im Mathematikunterricht rum geärgert.
Ich erinnere mich, dass ich ständig eine Parabelschablone, wie diese rumgeschleppt habe:

Mit dieser konntest du dann die Funktion f(x) = x² relativ einfach zeichnen. Mit der Matplotlib brauchen wir keine Schablone mehr
normparabel_graph.py
#! ./bin/python
# encoding: utf-8
import matplotlib.pyplot as plt
import numpy as np
def plot_normal_parabel():
# Erzeuge Datenpunkte für x-Werte von -3 bis 3
x = np.linspace(-3, 3, 100)
# Berechne die y-Werte für die Normalparabel
y = x**2
# Erstelle das Diagramm
plt.plot(x, y, label='Normalparabel: $y=x^2$')
# Beschriftungen und Titel hinzufügen
plt.xlabel('x-Achse')
plt.ylabel('y-Achse')
plt.title('Normalparabel')
# Legende hinzufügen
plt.legend()
# Funktion aufrufen, um die Normalparabel zu zeichnen
plot_normal_parabel()
# Diagramm anzeigen
plt.grid(True)
plt.show()
Die Methode plot_normal_parabel()
zeichnet uns den Graphen im Wertebereich von -3
bis 3
.
![Graph der Normalparabel von[-3,3]](https://i0.wp.com/raspithek.de/wp-content/uploads/2024/01/normal-parabel.png?resize=640%2C480&ssl=1)
In der Schablone ist üblicherweise auch die Sinus-Funktion eingekerbt, diese können wir mit der Matplotlib ins gleiche Diagramm zeichnen lassen. Dazu erweitern wir das obige Programm um die Methode plot_sinus()
def plot_sinus_function():
# Erzeuge Datenpunkte für x-Werte von -2π bis 2π
x = np.linspace(-2 * np.pi, 2 * np.pi, 100)
# Berechne die y-Werte für die Sinusfunktion
y = np.sin(x)
# Erstelle das Diagramm für die Sinusfunktion
plt.plot(x, y, label='Sinusfunktion: $y = \sin(x)$', color='blue')
# Legende hinzufügen
plt.legend()
Diese berechnet die Werte der Sinusfunktion im Bereich von -2π
bis 2π
.
Diese neue Methode rufen wir jetzt direkt nach plot_normal_parabel()
auf und zeigen das Diagramm wie gehabt an.
# Funktion aufrufen, um die Normalparabel zu zeichnen
plot_normal_parabel()
plot_sinus_function()
# Diagramm anzeigen
plt.grid(True)
plt.show()
Das Ergebnis kann sich sehen lassen.

Allgemeines
Die Vielzahl der verschiedenen Diagrammtypen kann ich unmöglich alle hier vorstellen, du findest aber genügend Webseiten, die dir Hilfestellung bieten. Grundsätzlich läuft das aber so ab:
- Definiere deine Daten
- Definiere die Labels zur Beschriftung der Achsen
- Optional: Definiere die Legende
- plotte das Diagramm
- Zeige das Diagramm an
Damit will ich Teil 23 des Python-Tutorials beschließen.