Ein gutes Bild sagt mehr als tausend Worte Datenverarbeitung und Visualisierung mit Python Jan Köhler Lars Berger Christian Drews 7.-8. April 2014 1 / 93 Übersicht Warum Python? Erste Schritte in Python numpy/scipy matplotlib 2 / 93 Warum Python? Python ist ... einfach, schnell, frei verfügbar (open source), besitzt eine Vielzahl von Erweiterungen (Modulen), sowohl zur Verarbeitung und Darstellung von Daten geeignet, aber auch als Programmiersprache für komplexe Softwareprojekte. I I I I Youtube Google EVE Online ... 3 / 93 Was uns erwartet ... >>> >>> >>> >>> >>> >>> import pylab DatenX, DatenY = lade_daten("./Daten/Wetter.dat") Ax = pylab.figure().gca() Ax.plot(DatenX, DatenY, lw = 2, label = "Wetter") Ax.set_ylabel("Temperatur") (...) 4 / 93 Woher bekomme ich Python? Windows: www.python.org: Offizielle Webseite Dokumentation und Tutorials ... Nur die Basispakete! Python(x,y) http://code.google.com/p/pythonxy Alle wichtigen Zusatzmodule Gängige Editoren und Entwicklungsumgebungen Alles was man braucht! Linux: Normalerweise vorinstalliert Mac: Normalerweise vorinstalliert 5 / 93 Die Spyder Konsole ... bereitet alles zum interaktiven Arbeiten vor: 6 / 93 Erste Schritte Einfaches Anwendungsbeispiel: >>> t = arange(100) >>> f = 0.02 >>> plot(sin(2*pi*f*t)) >>> sqrt(9) 3 >>> log(100) + (4+3)*2 18.6051701 >>> a = 14.32 >>> b = sqrt(0.04) >>> a * sqrt(a - b**3) + sin(a**2 +b) ... Bye bye Windows Taschenrechner! 7 / 93 Spyder Interactive Development Environment “Spyder is a powerful interactive development environment for the Python language with advanced editing, interactive testing, debugging and introspection features” 8 / 93 Erste Schritte in Python I Grundlegende Befehle: print ’Hallo Welt’ x = 2 print "x = ", x #Setze x = 2 #Ausgabe: x = 2 print "x + 2 = ", x+2 print "x * 2 = ", x*2 print "x^2 = ", x**2 #Ausgabe: x + 2 = 4 #Ausgabe: x * 2 = 4 #Ausgabe: x^2 = 4 print - Ausgabe von Daten # - Kommentare x =... - Variablen können direkt zugewiesen werden Ausprobieren! 9 / 93 Erste Schritte in Python II Variablenzuweisung in Python: i f s s = = = = 2 2.0 ’Dies ist ein String’ i #Integer #Float #String #s ist jetzt ein Integer Das Gleiche in C++: int i = 2; //Integer float f = 2.0; //Float char[] s = "Dies ist ein String"; //String Vorsicht: (Implizite Typisierung) a = 1.0 print a/2 b = 1 print b/2 print b/2.0 # -> 0.5 # -> 0 !!! # -> 0.5 10 / 93 Erste Schritte in Python II Weitere Datentypen: Listen (list) a = [’Hund’, ’Katze’, 100, 2.0] print a # -> [’Hund’, ’Katze’, 100, 2.0] print a[1] # -> ’Katze’ print a[0:2] # -> [’Hund’, ’Katze’] print a[2:] # -> [100, 2.0] print a[2:]*2 # -> [100, 2.0, 100, 2.0] print len(a) a[1] = ’Hund2’ print a a[0] = [1, 2] print a a.sort() print a # # # # # # # -> 4 -> Ersetzt ’Katze’ -> [’Hund’, ’Hund2’, 100, 2.0] Verschachtelte Listen -> [[1, 2], ’Hund2’, 100, 2.0] a wird sortiert (Methode!) -> [2.0, 100, [1, 2], ’Hund2’] Funktioniert für beliebige Datentypen slices (a[:3]) sind ein nützliches Werkzeug Listen sind Objekte mit Methoden (sort) 11 / 93 Erste Schritte in Python II Aufgaben: Benutze die Hilfe um mehr über Listen (list) zu erfahren Erstelle eine beliebige Liste a=[...] Welche Methoden haben Listen? Wozu dient append und reverse? Kehre die Reihenfolge der Elemente der Liste um. Erstelle eine neue Liste, die nur die ersten beiden Elemente enthält. a = [’Hund’, ’Katze’, 100, 2.0] a.reverse() print a b = a[0:2] 12 / 93 Erste Schritte in Python III if und else: y = 5 if y < 0: print elif y == print else: print "negativ" 0: "Null" if y > 10 print if y < 10 print and y < 20: "y liegt zwischen 10 und 20" or y > 20: "y liegt nicht zwischen 10 und 20" "positiv" # # Wenn < 0 # # Wenn voriges if ’wahr’, teste ob y = 0 # # Wenn keine Bedingung ’wahr’, dann: # Python benutzt Einrückung! (Vorsicht) Für Vergleiche wird == benutzt! x=2 ist eine Zuweisung, x==2 ein Vergleich. Bedingungen lassen sich beliebig mit and und or verknüpfen 13 / 93 Erste Schritte in Python III Beispiel: y = 2 if y % 6. == 0: print "y ist durch 6 teilbar" Aufgabe: Benutze eine if- Abfrage um y=0 zu setzen, falls y negativ ist. y = -1 print ’y = ’, y # -> y = -1 if y < 0: y = 0 print ’y = ’, y # teste ob y negativ ist # setze y = 0 # -> y = 0 14 / 93 Erste Schritte in Python IV Schleifen: for i in [’Hund’, ’Katze’, 100, 2.0]: # Fuer jedes Element in []: print "i = ",i # -> i = Hund ... print range(10) # -> [0, 1, 2, ... 8, 9] for i in range(10): print "i = ", i Aufgabe: Schreibe eine for-Schleife mit range(10), aber gib nur die i aus, die > 5 sind. for i in range(10): if i > 5: print i 15 / 93 Erste Schritte in Python IV Aufgabe: Erstelle eine Liste, die die Quadrate aller Zahlen von 0 bis 99 enthält. D.h.: [0, 1, 4, 9, 16, 25, ...] Hinweis: Benutze eine for-Schleife Hinweis: Beginne mit einer leeren Liste und erweitere mit .append() quadrate = [] for i in range(100): print i, i*i quadrate.append(i*i) print quadrate 16 / 93 Grundlegende Konzepte I Datei Ein/Ausgabe: read f = open("data/bsp1.txt", ’r’) for line in f: print line f.close() Ausprobieren! Jede line wird als Text eingelesen. Wie kommen wir an die Zahlenwerte? s l x y = = = = "10 15" s.split() float(l[0]) float(l[1]) #-> l = ["10", 15"] #-> y = 10.0 #-> x = 15.0 17 / 93 Grundlegende Konzepte I Aufgabe: Lese bsp1.txt ein und speichere die Zahlen der beiden Spalten in den Listen X, Y. Wende .split() auf line an. Wandel die Strings in float um. Benutze .append() um die Werte an X,Y anzuhängen. X = Y = f = for [] [] open("bsp1.txt", ’r’) line in f: l = line.split() X.append(float(l[0])) Y.append(float(l[1])) f.close() Plot Beispiel: from pylab import * und plot(X,Y) 18 / 93 Grundlegende Konzepte I Datei Ein-/Ausgabe: write f = open("ausgabe.txt",’w’) f.write("Hallo Datei! \n") f.close() open(filename, ’r’) - Datei zum Lesen öffnen open(filename, ’w’) - Datei zum Schreiben öffnen open(filename, ’a’) - Daten werden an bestehende Datei angehängt Aufgabe: Schreibe die Zahlen 0-100 in eine Datei. f = open("ausgabe.txt", ’w’) for i in range(101): f.write(str(i)+"\n") f.close() 19 / 93 Grundlegende Konzepte II Funktionen: def quadrat(x): return x*x # definiere quadrat(x) # x*x wird ’zurueck gegeben’ print quadrat(2) #-> 4 Default Argumente def f(x, a=1, b=0): y = a*x + b return y # definiere Funktion f() print f(1, 2, 0) print f(1) #-> 2 #-> 1 # y wird ’zurueck gegeben’ Funktionen beginnen mit dem Keyword def Es können beliebige Argumente (Zahl, String, Liste) übergeben werden Auf Einrückung achten! 20 / 93 Grundlegende Konzepte II Variablen innerhalb und außerhalb der Funktion def f(x): print "In f: Erhoehe x um 2" x = x + 2 print "In f: x = ", x return "fertig" x = 1 print "Vor Aufruf von f: x =", x s = f(x) print "Nach Aufruf von f: x = ", x Ausgabe: -> Vor Aufruf von f: x = 1 -> In f: Erhoehe x um 2 -> In von f: x = 3 -> Nach Aufruf von f: x = 1 21 / 93 Grundlegende Konzepte III Aufgabe: Schreibe eine Funktion, die in einer Liste alle Einträge < -990 in 0 ändert. [2.2, 3, 4.2, -999, 5] −→ [2.2, 3, 4.2, 0, 5] Benutze eine for-Schleife, um auf die einzelnen Elemente zuzugreifen Z.B.: for i in range( len(liste) ): Benutze liste[i], um an die einzelnen Einträge der Liste zu gelangen def clean_data(liste): for i in range(len(liste)): if liste[i] < -990: liste[i] = 0 22 / 93 Grundlegende Konzepte III Aufgabe: (simple Interpolation) Schreibe eine Funktion, die in einer Liste alle Einträge < -990 in den vorigen Eintrag ändert. [2.2, 3, 4.2, -999, 5] −→ [2.2, 3, 4.2, 4.2, 5] range(5) erzeugt die Liste [0, 1, 2, 3, 4] range(1, 5) erzeugt die Liste [1, 2, 3, 4] def fix_data(liste): for i in range(1, len(liste)): if liste[i] < -990: liste[i] = liste[i-1] Eine nützliche Funktion um einfache Datenlücken zu beheben. 23 / 93 Grundlegende Konzepte IV Nützliche Funktionen, die häufiger gebraucht werden, lassen sich in separate Module auslagern. Module Lege mit Spyder die Datei tools.py an Kopiere interpolate data nach tools.py Andere Dateien können nun tools importieren import tools liste = [2.2, 3, 4.2, -999, 5] tools.fix_data(liste) #importiere das Modul tools from tools import fix_data fix_data(liste) #importiere fix_data aus tools from tools import * #importiere alle Funktionen aus tools #benutze fix_data aus tools Damit man auf ein Modul zugreifen kann, muss es sich im gleichen Verzeichnis wie die ausgeführte Datei befinden, oder sich in einem Unterverzeichnis befinden, oder sich im PYTHONPATH befinden 24 / 93 Grundlegende Konzepte IV Es gibt zahllose vordefinierte Module: os/sys - Bieten Methoden um auf das Betriebssystem zuzugreifen (kopieren etc.) math - Enthält gängige mathematische Funktionen datetime - Enthält Methoden um Zeit und Datumsangaben zu bearbeiten gzip - Bietet direkten Zugriff auf gezippte Dateien pyqt - Grafische Benutzeroberflächen (Qt) numpy/scipy - Paket zum wissenschaftlichen Programmieren in Python matplotlib - ”Bibliothek zum Erstellen publikationsreifer Grafiken” ... 25 / 93 Abschlussaufgabe: Einlesen und Darstellen von Daten Aufgabe: Häufig sind Datensätze komplexer aufgebaut: Die Datei kuesten linien.dat enthält die Küstenlinien von Kontinenten und Inseln. Die einzelnen Küstenlinien sind durch ein > getrennt. 1.78464 5.563564 0.19244 5.669954 -2.771612 4.951822 > -3.434312 4.435222 ... Lese den Datensatz ein und plotte die einzelnen Küstenlinien. Benutze die Befehle from pyplot import * und plot(X, Y) Beginne mit X=[], Y=[] Teste in jeder Zeile ob ein > vorkommt. I I Wenn ja: Plotte alle bisher eingelesenen Daten und setze X=[], Y=[] Wenn nicht: Benutze .append() um die Werte an X,Y anzuhängen. 26 / 93 Numpy Numpy ... ist eine Erweiterung (ein Modul) für Python ist genau wie Python frei verfügbar ist schnell liefert eine Vielzahl hilfreicher Funktionen enthält numpy arrays! Numpy erleichtert den Umgang mit Daten! 27 / 93 Rückblick: Erste Schritte Erinnerung : Einfaches Anwendungsbeispiel: >>> t = arange(100) >>> f = 0.02 >>> plot(sin(2*pi*f*t)) # arange ist eine Numpy Funktion # sin ist eine Numpy Funktion # pi kommt aus Numpy >>> sqrt(9) # sqrt -> Numpy 3 >>> log(100) + (4+3)*2 # log -> Numpy 18.6051701 >>> a = 14.32 >>> b = sqrt(0.04) >>> a * sqrt(a - b**3) + sin(a**2 +b) ... 28 / 93 Arrays I Arrays sehen wie Listen aus >>> l=range(10) >>> l [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Liste >>> a=arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # Array >>> l[:3] [0, 1, 2] # Indizierung/Slicing >>> a[:3] array([0, 1, 2]) # Funktioniert auch bei Arrays 29 / 93 Arrays I Arrays sehen wie Listen aus ... sind aber anders >>> l+1 # Mit Listen kann man Traceback (most recent call last): # nicht rechnen File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "int") to list >>> l**2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ... >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> a+1 # Mit Arrays geht es array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) >>> a**2 array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81]) 30 / 93 Rückblick: Erste Schritte in Python IV Erinnerung: Aufgabe: Erstelle eine Liste, die die Quadrate aller Zahlen von 0 bis 99 enthält. D.h.: [0, 1, 4, 9, 16, 25, ...] Hinweis: Benutze eine for-Schleife Hinweis: Beginne mit einer leeren Liste und erweitere mit .append() quadrate = [] for i in range(100): print i, i*i quadrate.append(i*i) print quadrate 31 / 93 Arrays I Aufgabe: Erstelle ein Array, das die Quadrate aller Zahlen von 0 bis 99 enthält. D.h.: [0, 1, 4, 9, 16, 25, ...] Hinweis: Benutze arange Hinweis: Rechne mit dem Array quadrate=arange(100) quadrate=quadrate**2 print quadrate # Geht auch in einer Zeile # quadrate=arange(100)**2 32 / 93 Arrays II Arrays sehen wie Listen aus ... >>> >>> >>> >>> [5, l=range(10) l[0]=5 # Man kann Eintraege aendern l[1]=l[2]+l[3] # und mit ihnen rechnen l 5, 2, 3, 4, 5, 6, 7, 8, 9] >>> a=arange(10) # Das geht auch mit Arrays >>> a[0]=5 >>> a[1]=a[2]+a[3] >>> a array([5, 5, 2, 3, 4, 5, 6, 7, 8, 9]) 33 / 93 Arrays II Arrays sehen wie Listen aus ... sind aber anders >>> >>> >>> [0, l=range(10) l.append(20) # Listen kann man erweitern l 1, 2, 3, 4, 5, 6, 7, 8, 9, 20] >>> a=arange(10) >>> a.append(10) # Arrays nicht Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: ’numpy.ndarray’ object has no attribute ’append’ Vorsicht: Arrays sind keine Listen >>> b=append(a,20) >>> b array([ 0, 1, 2, # Erweiterung eines Arrays # nur durch eine Neuzuweisung 3, 4, 5, 6, 7, 8, 9, 20]) 34 / 93 Arrays II Aufgaben: Benutze die Hilfe, um mehr über Arrays zu erfahren Vergleiche die Methoden und Attribute von Listen und Arrays Wozu dienen mean und was ist dtype bei Arrays? Berechne den Mittelwert der ganzen Zahlen von 6 bis 33 I I mit einer Liste mit einem Array # mit Liste summe=0. anzahl=0. for i in range(6,34): summe=summe+i anzahl=anzahl+1 mittelwert_liste=summe/anzahl # mit Array mittelwert_array=arange(6,34).mean() 35 / 93 Rückblick: Erste Schritte in Python II Erinnerung: Variablenzuweisung in Python: i f s s = = = = 2 2.0 ’Dies ist ein String’ i #Integer #Float #String #s ist jetzt ein Integer Vorsicht: (Implizite Typisierung) a = 1.0 print a/2 b = 1 print b/2 print b/2.0 # -> 0.5 # -> 0 !!! # -> 0.5 36 / 93 Arrays III Typen >>> a=arange(10) # Typisierung implizit 10 -> int >>> a/2 array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]) >>> a=arange(10.) # 10. -> float >>> a/2 array([0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5]) Vorsicht: Arrays haben einen festen Typ >>> a=arange(10) >>> a[5]=10.5 >>> a array([ 0, 1, 2, # a -> Typ : int 3, 4, 10, 6, 7, 8, 9]) >>> a[5]="Hund" Traceback (most recent call last): ... ValueError: invalid literal for long() with base 10: ’Hund’ 37 / 93 Arrays III Erzeugen von Arrays >>> arange(10) # Kennen wir bereits array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) Die meisten Numpy Funktionen haben Arrays als Rückgabe >>> zeros(10,int) array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) >>> ones(10,float) array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) >>> sqrt(range(5)) array([0., 1., 1.41421356, 1.73205081, 2.]) Die Funktion array erzeugt ein Array aus der Eingabe >>> array(range(5)) array([0, 1, 2, 3, 4]) # Aehnlich wie : >>> float(5) # 5. 38 / 93 Arrays IV Indizierung und Masken Indizierung kann zum Filtern von Arrays verwendet werden >>> a=arange(5) >>> b=arange(0,5,2) >>> a array([0, 1, 2, 3, 4]) >>> b array([0, 2, 4]) >>> a[b] array([0, 2, 4]) 39 / 93 Arrays IV Indizierung und Masken Die Boolsche Algebra kann auf Arrays angewendet werden >>> a=arange(5) >>> a array([0, 1, 2, 3, 4]) >>> b=a>2 >>> b array([False, False, False, >>> a[b] True, True], dtype=bool) # Benutze b als Maske array([3, 4]) >>> c=a<4 >>> a[b*c] array([3]) # Erstelle eine zweite Maske # Verbinde beide Masken mit # einem logischen Und 40 / 93 Rückblick: Grunndlegende Konzepte III Erinnerung: Aufgabe: Schreibe eine Funktion, die in einer Liste alle Einträge < -990 in 0 ändert. [2.2, 3, 4.2, -999, 5] −→ [2.2, 3, 4.2, 0, 5] Benutze eine for-Schleife, um auf die einzelnen Elemente zuzugreifen z.B.: for i in range( len(liste) ): Benutze liste[i], um an die einzelnen Einträge der Liste zu gelangen def clean_data(liste): for i in range(len(liste)): if liste[i] < -990: liste[i] = 0 41 / 93 Arrays IV Aufgabe: Schreibe eine Funktion, die in einem Array alle Einträge < -990 in 0 ändert. [2.2, 3, 4.2, -999, 5] −→ [2.2, 3, 4.2, 0, 5] Erzeuge eine Maske, die alle Werte < -990 filtert Benutze die Maske, um die Werte in 0 zu ändern def clean_data(data_array): maske=data_array<-990 # Es geht auch kurz data_array[maske]=0 # data_array[data_array<-990]=0 42 / 93 Arrays V Mehrdimensionale Arrays Bisher haben wir mit 1D Arrays gearbeitet >>> a=ones(3) >>> a array([1., 1., 1.]) >>> a.shape # shape ist ein Attribut von Arrays (3,) # a ist ein 1D Array der Laenge 3 >>> b=ones((3,3),int) # Achtung: Explizite Typisierung! >>> b array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) >>> b.shape (3, 3) # b ist ein 2D Array der Dimension 3*3 43 / 93 Arrays V 1D Arrays sind wie Zeilenvektoren Zeile a=ones(3) 0 a[0]=1. 1 a[1]=1. 2 a[2]=1. 44 / 93 Arrays V 2D Arrays sind wie Matrizen/Tabellen 0 a=ones((3,3)) Spalte 1 2 0 a[0,0]=1. a[0,1]=1. a[0,2]=1. 1 a[1,0]=1. a[1,1]=1. a[1,2]=1. 2 a[2,0]=1. a[2,1]=1. a[2,2]=1. Zeile 45 / 93 Rückblick: Grundlegende Konzepte I Erinnerung: Datei Ein/Ausgabe: read f = open("bsp1.txt", ’r’) for line in f: print line f.close() Ausprobieren! Jede line wird als Text eingelesen. Wie kommen wir an die Zahlenwerte? s l x y = = = = "10 15" s.split() float(l[0]) float(l[1]) #-> l = ["10", 15"] #-> y = 10.0 #-> x = 15.0 46 / 93 Numpy Datei Ein/Ausgabe Eingabe: loadtxt >>> data = loadtxt("bsp1.txt") Die gesamte Datei wird auf einmal gelesen. Wie kommen wir an die Zahlenwerte? Ganz einfach ... >>> x = data[:,0] >>> y = data[:,1] Und jetzt plotten wir x gegen y ... >>> plot(x,y) 47 / 93 Rückblick: Grundlegende Konzepte I Erinnerung: Aufgabe: Lies bsp1.txt ein, und speichere die Zahlen der beiden Spalten in den Listen X, Y. Wende .split() auf line an. Wandel die Strings in float um. Benutze .append() um die Werte an X,Y anzuhängen. X = Y = f = for [] [] open("bsp1.txt", ’r’) line in f: l = line.split() X.append(float(l[0])) Y.append(float(l[1])) f.close() Hat sich erledigt! 48 / 93 Numpy Datei Ein/Ausgabe Ausgabe: savetxt In aller Kürze ... >>> savetxt(dateiname,data_array) sollte es tun! Aufgabe: Schreibe mit Hilfe von savetxt die Zahlen 0-100 in die Datei ausgabesavetxt.txt. >>> savetxt("ausgabesavetxt.txt",arange(101)) Schöner ist evtl. >>> savetxt("ausgabesavetxt2.txt",arange(101),fmt="%i") 49 / 93 Histogramme Was macht histogram Wir haben folgende Punkte : array([0.3,0.66,1.1,1.8,1.9,2.4]) 1 0 2 3 Wir moechten wissen wie viele Punkte haben wir in den Intervallen? 0 0 0-1 2 2-3 1-2 1 2 Numpy histogram zaehlt fuer uns! 1 3 2 1 3 3 50 / 93 Histogramme Wie verwendet man histogram Wir haben folgende Punkte : array([0.3,0.66,1.1,1.8,1.9,2.4]) 1 0 2 3 Wir moechten wissen wie viele Punkte haben wir in den Intervallen? 0 0 0-1 2 2-3 1-2 1 2 Numpy histogram zaehlt fuer uns! 1 3 2 1 3 3 >>> points=array([0.3,0.66,1.1,1.8,1.9,2.4]) >>> histogr,intervals=histogram(points,arange(4)) >>> histogr array([2, 3, 1]) >>> intervals array([0, 1, 2, 3]) 51 / 93 Vorbereitung auf Matplotlib Aufgabe: Wir bereiten uns nun auf den folgenden Teil, der sich intensiv mit der Visualisierung von Daten beschäftigen wird, vor. Die Datei wetter kiel.txt enthält Langzeitwetterdaten von der Wetterstation in Kiel Holtenau. Ziel ist es mit Hilfe des bisher Gelernten einen Loader für diesen Datensatz zu schreiben. Wenn die Daten geladen wurden sollten folgende Arrays im Speicher sein Zeit → Zeiten möglichst als datetime Objekte LTemp → Luftemperatur BTemp → Bodentemperatur LDruck → Luftdruck Regen → Regenmenge Schnee → Schneemenge Bedeckung → Wolkenbedeckung 52 / 93 Vorbereitung auf Matplotlib Aufgabe: Benutze loadtxt zum laden der Daten. Folgende Argumente sind hilfreich usecols skiprows unpack delimiter Konvertieren der Zeiten mit : import datetime datetime.datetime.strptime(str(int(date)),"%Y%m%d")) Wer mit dem Laden der Daten fertig ist, kann versuchen Histogramme aus den Daten zu erstellen und diese darzustellen. hist aus pylab kann gleichzeitig histogrammieren und plotten 53 / 93 Matplotlib Matplotlib is das Plotting-Interface zu den wissenschaftlichen Python-Bibliotheken Numpy und Scipy. Matplotlib bietet ... einfache und verständliche Syntax eine unkomplizierte Einbindung in Python (fast) grenzenlose Möglichkeit zur Darstellung von Daten regelmäßige Funktions-Erweiterung dank steter Weiterentwicklung eine umfangreiche Dokumentation inklusive hunderter Beispiel-Plots Matplotlib bietet deswegen vor allem eins: Spaß beim Arbeiten mit wissenschaftlichen Daten 54 / 93 Was uns erwartet ... >>> >>> >>> >>> >>> >>> import pylab DatenX, DatenY = lade_daten("./Daten/Wetter.dat") Ax = pylab.figure().gca() Ax.plot(DatenX, DatenY, lw = 2, label = "Wetter") Ax.set_ylabel("Temperatur") (...) 55 / 93 Erste Schritte in Matplotlib I Der erste Plot: import pylab # Erzeuge Daten x = arange(10) y = x**2 # Erzeuge Figur Fig = pylab.figure() # Erzeuge Achse Ax = Fig.gca() # Plotte Daten Ax.plot(x, y) 56 / 93 Matplotlib - Hilfe Hilfe in Python Auflistung von Funktionen und Methoden >>> import pylab >>> Ax = pylab.figure().gca() >>> Ax.<Tab> <Funktionen des Ax Objektes> >>> dir(Ax) <Funktionen des Ax Objektes> Hilfe zu Funktionen und Methoden >>> Ax.plot? # nur iPython <Docstring von Ax.plot> >>> help(Ax.plot) <Docstring von Ax.plot> 57 / 93 Matplotlib - Hilfe Hilfe im Web Dokumentation: http://www.matplotlib.org/contents Beispiele: http://www.matplotlib.org/gallery Figure : Snapshot der Matplotlib Gallery 58 / 93 Erste Schritte in Matplotlib I Aufgabe: Benutze die Hilfe um mehr über den plot Befehl herauszufinden Welche Argumente gibt es? Wie kann man den Stil des Plots verändern? >>> from numpy import linspace, sin, pi >>> x = linspace(0,2*pi,100) >>> P1, P2, P3 = sin(x), sin(0.5*x), sin(2*x) Stelle P1, P2, P3 als Funktion von x dar. Benutze dafür Farben und Stile vergleichbar zu dem nachfolgenden Plot: 59 / 93 Erste Schritte in Matplotlib I Achsen Parameter I Erstellung der Achse und Daten Ax = pylab.figure().gca() Ax.plot(arange(10), arange(10), label="Daten", marker="*") Achsenbeschriftung Ax.set_xlabel("X Label",fontsize=9) Ax.set_ylabel("Y Label",color="red") Achsenbereich Ax.set_ylim(-2,8) Ax.set_xlim(0,10) 60 / 93 Erste Schritte in Matplotlib I 61 / 93 Erste Schritte in Matplotlib I Achsen Parameter II Erzeugung einer sekundären y-Achse Ax2=Ax.twinx() Ax2.plot(arange(10),1.5*arange(10),color="green") Ax2.set_ylabel("Y2-Label",color="green") Achsenmarkierung Ax.set_xticks([2,4,6]) # Explizite x-Tick Markierung Ax.set_minorticks_on() # Anschalten der Zwischen-Ticks Ax.set_xticks([3,5,7],minor=True) # Explizite Zwischen-Ticks Erzeugung eines Rasters Ax.grid(which=’both’,axis=’both’) 62 / 93 Erste Schritte in Matplotlib I Achsen Parameter II Achsenlegende Ax.legend() 63 / 93 Erste Schritte in Matplotlib I Aufgabe I Visualisiere den zeitlichen Verlauf der Temperatur und des Drucks der Wetterstation Kiel Holtenau. Ihr könnt hierfür zum Einlesen der Wetterdaten entweder euren eigenen oder den bereitgestellte Loader ./aufgaben/wetter holtenau.py benutzen. Euer Endergebnis sollte in etwa wie folgt aussehen: 64 / 93 Erste Schritte in Matplotlib I Aufgabe II (Optional) Wer eine Herausforderung sucht, kann sich auch gerne an folgendem Plot versuchen, welcher mit dem Ax.scatter() Befehl erzeugt wurde. Die Regenmenge wird durch die Größe der Kreise dargestellt Die Temperatur wird durch die Farbe der Kreise visualisiert Die Menge an Schneefall wird durch die Quadratgröße bestimmt 65 / 93 Matplotlib - Fortgeschrittene Funktionen Matplotlib bietet eine große Zahl an weiterführenden Plot Techniken. Durchstöbert einfach die Beispiel Gallerie http://www.matplotlib.org/gallery wenn ihr etwas bestimmtes sucht. Hier werden wir die 3 gebräuchlichsten Techniken kurz vorstellen. Isokonturlinien >>> Ax.contour(*args) Isokonturflächen >>> Ax.contourf(*args) Kontinuierliche Farbkonturen >>> Ax.pcolormesh(*args) 66 / 93 Matplotlib - Fortgeschrittene Funktionen Drei einfache Beispiele für Isokonturlinien (links), Isokonturflächen (mitte) und einer Kombination aus einer Farbkontur und Isokonturlinien (rechts). 67 / 93 Einschub: 2D-Histogramme Wenn wir folgende Punkte haben ... 3 2 1 00 1 2 3 68 / 93 Einschub: 2D-Histogramme Und wissen möchten wieviele Punkte in den Quadraten liegen ... 3 2 1 00 1 2 3 69 / 93 Einschub: 2D-Histogramme Können wir analog zu histogram, histogram2d verwenden. 3 1 1 0 1 0 0 0 2 1 2 1 00 1 2 3 70 / 93 Einschub: 2D-Histogramme Wie verwendet man histogram2d? 3 1 1 0 1 0 0 0 2 1 2 1 00 1 2 3 >>> P_x=array([0.3,0.66,1.1,1.8,1.9,2.4]) >>> P_y=array([1.5,2.9,0.5,2.4,0.9,0.5]) >>> histogr,int_x,int_y=histogram2d(P_x,P_y,(arange(4),arange(4))) >>> histogr array([[ 0., 1., 1.], [ 2., 0., 1.], [ 1., 0., 0.]]) 71 / 93 Matplotlib - Fortgeschrittene Techniken Ein 2D-Histogramm kann z.B. mit pcolormesh dargestellt werden 3 3.0 1 0 1 2.5 2 2.0 0 1 0 1.5 1 1 1.0 0 00 2 1 2 1 2 0.5 3 0.00.0 0.5 1.0 1.5 2.0 2.5 3.0 0 Die folgenden Zeilen erzeugen den rechten Plot. >>> fig=figure(figsize=(10.,10.)) >>> pcolormesh(int_x,int_y,histogr.T) >>> colorbar(ticks=[0,1,2]) Keine Angst: Eine ausführliche Erklärung folgt! 72 / 93 Matplotlib - Fortgeschrittene Techniken Um die Funktionsweisen von Ax.contour(*args), Ax.contourf(*args) und Ax.pcolormesh(*args) zu erläutern, werden wir zunächst einen zufällig generierten Datensatz erzeugen und diesen mittels des Ax.pcolormesh(*args) Befehls darstellen. Erzeugung eines zufällig generierten Datensatzes xValues = append(normal(15, normal(20, yValues = append(normal(10, normal(15, 2, 5, 3, 2, size=1e6), \ size=1e6)) size=1e6), \ size=1e6)) Einordnen der Zufallszahlen in ein 2D Histogramm: Histogram, xedges, yedges = histogram2d(xValues, yValues, \ bins = (arange(10,30,0.2), arange(0,20,0.2))) 73 / 93 Matplotlib - Ax.pcolormesh(*args) Bevor wir das 2D Histogramm plotten, einige Worte zur der allgemeinen Syntax von Ax.pcolormesh(*args) Syntax - Pcolormesh Ax.pcolormesh(X, Y, H, *args=vals) Dabei stellen X und Y die Bin Kanten in x- und y-Richtung des Histogramms H dar. Dabei steht args für optionale Argumente, die an die pcolormesh Methode übergeben werden können. Die gebräuchlichsten Argumente sind dabei: cmap: Übergabe einer spezifischen Colormap vmin / vmax: unterer / oberer Grenzwert der pcolormesh Darstellung alpha: Transparenz der Darstellung Die Argument cmap und vmin, vmax werden wir später noch genauer beschreiben 74 / 93 Matplotlib - Ax.pcolormesh(*args) Der endgültige Plotbefehl für unsere Zufallsdaten ist denkbar einfach. Ax.pcolormesh(Xedges, Yedges, Histogram.T) Figure : Der einfache pcolormesh Befehl 75 / 93 Matplotlib - Ax.pcolormesh(*args) Bevor es zu der ersten Übung geht, gilt es eine Sache zu beachten: Histogram2D in Kombination mit contour und contourf Das erzeugte Histogramm mit histogram2d beinhaltet, wie üblich für numpy arrays, in der 0-ten Dimension die x- und in der 1-ten Dimension die y-Werte. pcolormesh, contour und contourf benötigt jedoch ein umgekehrtes Format, d.h. um das Histogramm aus histogram2d zu nutzen, müssen wir das Histogramm transponieren (x und y vertauschen). Zusätzlich gibt histogram2d die Bin Kanten zurück, während contour und contourf die Bin Position benötigen (gilt nicht für pcolormesh). Ax.contourf(Xedges[:-1], Yedges[:-1], Histogram.T) Ax.contour(Xedges[:-1], Yedges[:-1], Histogram.T) Ax.pcolormesh(Xedges, Yedges, Histogram.T) 76 / 93 Matplotlib - Fortgeschrittene Techniken Aufgabe: Plotte durch Kombination des Ax.contour(*args) und Ax.contourf(*args) Befehls unseren Zufallsdatensatz in folgender Darstellung: 100 010 15 400 5 Benutzt das Argument levels in Ax.contour(*args) Benutzt die Methode Ax.clabel(*arg) 100 10 200 Y-Werte 800 15 Benutzt die gängigen Methoden für die Achsendarstellung 20 X-Werte 25 77 / 93 Matplotlib - Colorbar Wir haben eben gelernt, wie wir mit Ax.clabel(*args) den Isokonturlinien eine Beschriftung zuweisen können. Jedoch hat die Farbdarstellung von pcolormesh und contourf noch keinen Bezug zu den Intensitäten der Daten. Hierfür verwenden wir die Colorbar aus Matplotlib. Erzeugung der - Colorbar Figure = pylab.figure() Ax = Figure.gca() # Auswahl der vorgefertigten Colormaps aus Matplotlib colormap = pylab.cm.get_cmap("jet") # Erzeugung des Farbkontur mit der ausgewaehlten colormap Mesh = Ax.pcolormesh([...], cmap=colormap) # Erzeugung der Colorbar colorbar = Figure.colorbar(Mesh) # Setzen des Colorbar Beschriftung colorbar.set_label("Intensity") 78 / 93 Matplotlib - Colorbar Wir haben eben gelernt, wie wir mit Ax.clabel(*args) den Isokonturlinien eine Beschriftung zuweisen können. Jedoch hat die Farbdarstellung von pcolormesh und contourf noch keinen Bezug zu den Intensitäten der Daten. Hierfür verwenden wir die Colorbar aus Matplotlib. Figure : Eine typische Colorbar 79 / 93 Matplotlib - Colorbar Syntax - Colorbar Figure.colorbar(Mesh, *args=vals) Dabei stellt Mesh das Objekt dar, welches von pcolormesh, contour und contourf zurückgegeben wird. Dabei steht args für optionale Argumente, die übergeben werden können. Die gebräuchlichsten Argumente sind dabei: orientation: Orientierung der Colorbar ax: Achse auf der die Colorbar dargestellt wird ticks: Definitiert die Colorbar ticks pad: Abstand der Colorbar zur Achse 80 / 93 Matplotlib - Colorbar Noch ein kleiner Hinweis zur Benutzung der colormap für die Farbkontur-, Isokonturlinien- und Isokonturflächendarstellung Syntax - Colormap colormap = pylab.cm.get_cmap(arg) arg steht dabei für den Namen einer von vielen fertigen colormaps in matplotlib. Eine vollständige Liste der colormaps findest du unter http://wiki.scipy.org/Cookbook/Matplotlib/Show colormaps Hinweis zum Ausblenden/Markieren von Daten colormap.set_under("white") colormap.set_over("green") Ax.pcolormesh([...], vmin=5, vmax=10) Dies würde unabhängig von der gewählten colormap alle Intensitäts Werte unter 5 bzw. über 10 in weiß bzw. grün darstellen 81 / 93 Matplotlib - Fortgeschrittene Techniken Aufgabe I Stellt die globale Temperatur als Funktion des Längen- und Breitengrades mit Hilfe von Ax.pcolormesh(*arg) dar. Hier ist ein mögliches Beispiel der Darstellung: Benutzt Ax.pcolormesh(*args) Verwendet die Colorbar Benutzt google für alles Weitere ;-) 82 / 93 Matplotlib - Fortgeschrittene Techniken Aufgabe II (optional) Stellt zusätzlich die Küstenlinien dar, welche in der Datei kuesten linien.dat definiert sind. Plottet zudem einige ausgewählte Städte mit Namen in die Weltkarte. Benutzt Ax.plot(*args) für die Küstenlinien und Städte Verwendet die Ax.set label(*arg) für die Städtenamen Benutzt google für alles Weitere ;-) 83 / 93 Matplotlib - Multipanel Plots Bei komplexeren Datensätzen bietet es sich häufig an, mehrere Achsen auf einer Grafik unterzubringen. =⇒ Multi-Achsen Plots (Multiplots) Automatische Achsenerzeung nr_x = 2 Plot 1 60 nr x - Anzahl der Achsen in x-Richtung nr y - Anzahl der Achsen in y-Richtung i - Aktueller plot (1, ..., nr x*nr y) 50 40 i=1 30 10 1 2 3 60 4 5 Plot 3 6 7 8 9 1 2 3 4 5 Plot 4 6 7 8 9 6 7 8 9 6 7 8 9 50 40 40 i=3 30 20 i=4 30 20 10 10 1 2 3 60 4 5 Plot 5 6 7 8 9 0 0 1 2 3 60 50 4 5 Plot 6 50 40 40 i=5 30 20 i=6 30 20 10 0 0 0 0 60 50 0 0 i=2 30 20 10 0 0 Plot 2 60 50 40 20 nr_y = 3 import pylab Figure = pylab.Figure() Ax = Figure.add_subplot(nr_x, nr_y, i) Ax.plot(xdata, ydata) 10 1 2 3 4 5 6 7 8 9 0 0 1 2 3 4 5 84 / 93 Matplotlib - Multipanel Plots Automatische Achsenerzeung - Fine tuning #Setzt horizontalen und vertikalen Abstand = 0 pylab.subplots_adjust(hspace =0, wspace =0) # Nebeneinander liegende Achsen teilen sich die y-Achse Ax1 = Figure.add_subplot(1,2,1) Ax2 = Figure.add_subplot(1,2,2, sharey=Ax1) # Entferne y-Beschriftung von Ax2 Ax2_label = Ax2.get_yticklabels() pylab.setp(Ax2_label, visible=False) 1.0 0.8 0.6 0.4 0.2 0.0 0.0 0.2 0.4 0.6 0.8 0.0 1.0 0.2 0.4 0.6 0.8 1.0 85 / 93 Matplotlib - Multipanel Plots Aufgabe: tan(x) cos(x) sin(x) Erzeuge eine Figure die Sinus, Cosinus und Tangens in drei übereinanderliegenden Achsen darstellt. Das Ergebnis sollte in etwa wie folgt aussehen: 1.0 0.5 0.0 0.5 1.0 1.0 0.5 0.0 0.5 1.0 10 5 0 5 10 0 2 4 x 6 8 10 86 / 93 Matplotlib - Multipanel Plots Achsenerzeugung von Hand import pylab Figure = pylab.figure() Ax1 = pylab.axes([0.1, 0.1, 0.8, 0.8]) # Erzeugung der ersten Achse [x-pos, y-pos, breite, hoehe] Ax2 = pylab.axes([0.2, 0.2, 0.3, 0.3]) # Erzeugung der zweiten Achse Ax1.plot( sin(arange(0, 2*pi, 0.01))) Ax2.plot( cos(arange(0, 2*pi, 0.01))) 1.0 0.8 0.5 0.0 0.8 1.0 0.3 0.5 0.0 0.3 0.5 0.5 0.2 1.00 100 200 300 400 500 600 700 0.2 0.1 1.0 0 100 200 300 400 500 600 700 0.1 87 / 93 Matplotlib - Letzte Anmerkungen Globale Einstellungen Bei umfangreicheren Plot ist es oftmals hilfreich die Standardeinstellungen von pylab zu ändern. Hierzu verwendet man rcParams aus matplotlib: from matplotlib import rcParams rcParams[’font.size’] = 20 Die Standardschriftgröße (12) wird auf 20 gesetzt. rcParams[’lines.linewidth’] = 3 Die Standardliniendicke (1) wird auf 3 gesetzt. Speichern von Plots Natürlich ist es auch möglich einen Plot direkt und mit den gewünschten Parametern zu speichern. Figure.savefig("Bildname.pdf", *arg) Genug mit neuen Informationen, kommen wir zur letzten Aufgabe! 88 / 93 Matplotlib - Multipanel Plots Aufgabe: Erstelle den folgenden Plot: 89 / 93 Ausblick und Zusammenfassung Ihr habt bereits viele Dinge kennengelernt, die euch den Umgang mit der Programmiersprache Python als wissenschaftliches Werkzeug erleichtern werden. Funktionsweise und Möglichkeiten von Python Umgang mit numpy, wie liest man Dateien effizient ein Einfache Plot Techniken wie Ax.plot(*arg) und Ax.scatter(*arg) Fortgeschrittene Plot Techniken wie Ax.contour(*arg) und Ax.pcolormesh(*arg) Nutzt unsere Musterlösungen und Handouts gerne als ”Startpunkt” für eure eigene Arbeit! Aber ... Man lernt niemals aus! 90 / 93 Ausblick und Zusammenfassung Figure : Pie Charts! [1] Figure : 3D Plots! [1] [1] Aus http://www.matplotlib.org/gallery 91 / 93 Ausblick und Zusammenfassung Figure : Vektorfelder! [1] Figure : Interaktive Animation! [2] [1] Aus http://www.matplotlib.org/gallery [2] Aus eigener Forschung 92 / 93 Ausblick und Zusammenfassung Wenn ihr noch Fragen zu Python, numpy oder matplotlib habt, wendet euch gerne an uns <[email protected]> <[email protected]> <[email protected]> Die Musterlösungen, Handouts und Vorlesungsfolien findet ihr unter: http://www.ieap.uni-kiel.de/et/people/koehler/PyKurs 93 / 93