Matplotlib Python Tutorial Teil 23

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

Python Logo (CC-BY-SA The people from the Tango! project / Wikipedia)
Matplotlib
Python Logo (CC-BY-SA The people from the Tango! project / Wikipedia)
1Python Programmierkurs
2Python: Methoden
3Kontrollstrukturen
4Strings in Python
5Container
6Objekte in Python
7Module
8Exceptions in Python
9Typkonvertierung
10Python und Dateien
11Datum und Zeit mit Python verarbeiten
12Multithreading
13Netzwerk in Python
14Logging in Python
15GPIO
16Automatische Tests
17Datenbanken mit Python
18Python: Generatoren und List Comprehension
19Python: Webseiten mit Flask
20Python virtuelle Umgebungen
21Interrupts & Signale
22NumPy
23Matplotlib
24match
25Reguläre Ausdrücke Python Tutorial Teil 25

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.

Matplotlib Balkendiagramm der Geschlechter mit zwei Säulen (rot=Mädchen und blau=Jungs)
Matplotlib Balkendiagramm der Geschlechter mit zwei Balken (rot=Mädchen und blau=Jungs)

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.

Gestapeltes Säulendiagramm mit dem Verkauf verschiedener Obstsorten über drei Jahre
Gestapeltes Säulendiagramm mit dem Verkauf verschiedener Obstsorten über drei Jahre

Balkendiagramm

Gestapeltes Säulendiagramm mit den I/O-Performance Messungen aus dem Pineberry Post
Gestapeltes Säulendiagramm mit den I/O-Performance Messungen aus dem Pineberry Post.

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:

Parabelschablone (Quelle: Wikipedia CC-BY-SA 2.0 WikipediaMaster)
Parabelschablone (Quelle: Wikipedia CC-BY-SA 3.0 WikipediaMaster)

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]
Graph der Normalparabel von[-3,3]

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 .

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.

Die Graphen von f(x)=x² und f(x) = sin(x) in einem Diagramm.
Die Graphen von f(x)=x² und f(x) = sin(x) in einem Diagramm.

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.

Schreibe einen Kommentar

WordPress Cookie Hinweis von Real Cookie Banner