wissenschaftliche programmierung mit python - für meteorologie und atmosphärenforschung martin g....
TRANSCRIPT
Wissenschaftliche Programmierung mit Python
- für Meteorologie und Atmosphärenforschung
Martin G. Schultz
Teil 6: Plotting, Part 2
ANDERE PLOTS, 2D DARSTELLUNGEN, KARTEN
2
1. Box and whisker plots
3
Aus der Matplotlib.axes Dokumentation:
…
Mehrere Datenreihen können als Liste von Listen (bzw. numpy arrays) übergeben werdenBeispiel für einfachen Boxplot:
Gestaltung des Boxplots
4
Boxplot liefert ein dictionary zurück, in dem folgende Informationen gespeichert sind:• medians: Liste von Line2D Objekten• fliers: Liste von Line2D Objekten• whiskers: Liste von Line2D Objekten• boxes: Liste von Line2D Objekten (patch_artist=False) oder
PathPatch Objekten (patch_artist=True)• caps: Liste von Line2D Objekten
Um dann z.B. die Box-Füllfarbe zu ändern muss man über die einzelnen Lines oder Patches iterieren (oder die plt.setp() Methode verwenden):
5
Box-
/Whi
sker
plot
Als erstes kümmern wir uns wieder um das Einlesen der Daten. Wiegehabt werden wir csv2rec benutzen. Zuvor definieren wir allerdingszwei Funktionen, die die Datenreihen in monatliche Abschnitte zerlegen:
für die Indizes brauchen wir nur die Datumswerte
Anwendungsbeispiel
Modulimport: keine unbekannten
Wir legen eine Liste von Listen an
Der jeweilige Ausschnitt der Datenwird als numpy array in der Listeabgelegt.
6
Box-
/Whi
sker
plot
Nun erfolgt das Einlesen der Daten
Ermitteln der Indizes
Einsortieren der Daten
7
Box-
/Whi
sker
plot
Hier kommt der Hauptteil der Plotarbeit
Das Definieren spezieller Unterroutinenmacht den Code lesbarer
Auch diese Anweisungen könnte manin Unterroutinen „verstecken“…
8
Box-
/Whi
sker
plot
Die Details der Formatierung
Hier wird das dictionary übergeben, welchesboxplot zurückliefert
Im Beispielprogramm sind diese Funktionen im Kopfteil definiert
9
Box-
/Whi
sker
plot
Weiter geht‘s im Hauptprogramm
Hier werden einzelne ticklabels unsichtbargemacht
10
Box-
/Whi
sker
plot
Nun noch die Legende
Wir benutzen eine axes.legend statt einer figure.legend,damit die Legende mittig unter dem Plot selbst ist!
Und zum Schluss speichern und anzeigen
11
ErgebnisBo
x-/W
hisk
erpl
ot
Karten und Vertikalschnitte
12
Bei der Auswertung von Simulationen mit meteorologischen oder Erdsystemmodellen werden oftmals Kartendarstellungen oder vertikale Schnitte benötigt.Python stellt für Karten die Basemap Ergänzung zu matplotlib bereit. Im Zuge der Darstellung vertikaler Schnitte werden wir uns auch mit (einfacher) Interpolation befassen.
Zum Üben benutzen wir die Datei MACC_20121027_0001.nc (zu finden unter ftp://sv02.meteo.uni-bonn.de/pub/maschu/python/data/MACC_20121027_0001.nc), der übrigens mit dem auf Python und javascript basierenden Web-Interface http://macc.icg.kfa-juelich.de:50080 (demnächst http://join.iek.fz-juelich.de) erzeugt wurde.
Aufwärmen: netcdf Dateien
13
Schauen wir uns erst einmal an, was in der netcdf Datei enthalten ist:
Wir erhalten einen Überblick über die Variablennamen, deren Typ, den Dimensionen und den Metadaten-Attributen. Beispiel:
Hier steht der Variablenname
Aufgaben1. Lese den ersten und den letzten Zeitschritt der Variablen vmr_ch2o aus
der Datei MACC_20121027_0001.nc ein und speichere diese Daten in der Variable ch2o.
2. Nun lese das dritte „level“ derselben Variablen für alle Zeitschritte ein. Wie erfährst du, welche Dimensionen deine Daten dann haben?
3. Informationen über die Vertikalkoordinate sind in den Variablen lev, bzw. in a, b und ps gespeichert. Welches level ist das „surface level“? Lese jeweils das unterste level für die Variablen vmr_ch2o und vmr_o3 am 9. Zeitschritt aus.
4. (*) Wie könntest du dir eine Zeitreihe der vmr_o3 Daten im untersten level für die Koordinaten lon=7.0667, lat=50.7333 extrahieren?
Kartenprojektionen
15
Das Basemap Modul stellt diverse Projektionen zur Verfügung. Beispiele sind:
Kartenprojektionen
16
Für jede Projektion gibt es verschiedene Optionen. Dokumentation unter http://matplotlib.org/basemap/users/mapsetup.html. Beispiel:
m (die Instanz des Basemap Objektes) enthält alle benötigten Informationen zur Koordinatentransformation und zum Zeichnen von Kontinenten, etc.Viele der Zeichenroutinen von matplotlib (z.B. contour, contourf) werden von Basemap dupliziert und ggf. durch Koordinatentransformationen ergänzt.
Zeichnen von Kontinenten etc.
17
Variante 1: Zeichnen von VektordatenVerfügbare Auflösungen*: c(oarse), l(ow), i(ntermediate), h(igh), f(ull)
* muss bereits bei der Definition der Projektion angegeben werden
Beispiel:
Zeichnen von Kontinenten etc.
18
Zeichnen von Kontinenten etc.
19
Variante 2: Pixelgrafik als Hintergrund
bluemarble shadedrelief etopo
Zeichnen von Kontinenten etc.
20
Hier der Sourcecode zu den letzten Beispielen:
warpimage kann ein beliebiges Bild über die Erde legen, sofern das Bild globale Abdeckung hat, ein regelmäßiges Längen- und Breitengitter aufweist, und bei -180 und -90 beginnt. Der Dateiname kann auch eine URL sein (s.o.).
Eigene Daten auf eine Karte zeichnen
21
Basemap stellt folgende Plotroutinen bereit, die größtenteils an matplotlib „weitergereicht“ werden. Man kann genauso gut mit plt.*** plotten; manchmal ist jedoch das Koordinatenhandling einfacher, wenn die Basemap-Version benutzt wird.barbs(x, y, u, v, *args, **kwargs)contour(x, y, data, *args, **kwargs)contourf(x, y, data, *args, **kwargs)hexbin(x, y, **kwargs)imshow(*args, **kwargs)pcolor(x, y, data, *args, **kwargs)pcolormesh(x, y, data, *args, **kwargs)plot(*args, **kwargs)quiver(x, y, u, v, *args, **kwargs)scatter(*args, **kwargs)streamplot(x, y, u, v, *args, **kwargs)
zusätzliches keyword: latlon=FalseWird latlon auf True gesetzt, werden x und y als longitude und latitude interpretiert (sonst Projektionskoordinaten)
Ein erster Versuch: Contour
22
Code aus map_demo_v01.py
Das Ergebnis…
23
Problem: die longitude Daten belegen den Wertebereich 0..360 Grad, die Kartenprojektion verlangt aber -180..+180 Grad.
map_demo_v01.py
Nutze Basemap Routinen für die Koordinatentransformation
24
Code aus map_demo_v02.py
…
Das Ergebnis…
25
Noch nicht so schön: Konturlinien zeigen kaum Farbkontrast.Problem: Werte sind „logarithmisch“, Konturskalierung linear
map_demo_v02.py
Nutze Basemap Routinen für die Koordinatentransformation
26
Code aus map_demo_v02.py
…
Das norm keyword legt die Umrechnung der Werte in den Zahlenbereich 0..1 fest.Folgende Normen stehen zur Auswahl:• NoNorm• Normalize• LogNorm
Das Ergebnis…
27
… vielleicht doch lieber gefüllte Konturlinien?
map_demo_v03.py
Bei gefüllten Konturplots ist zorder nützlich
28
Code aus map_demo_v04.py
…
Das norm keyword legt die Umrechnung der Werte in den Zahlenbereich 0..1 fest.Folgende Normen stehen zur Auswahl:• NoNorm• Normalize• LogNorm
Das Ergebnis…
29
Kommt dem gewünschten Ergebnis doch schon ziemlich nahe…
map_demo_v04.py
ohne zorder zorder = 3
Feinkontrolle des Farbbalkens
30
Code aus map_demo_v05.py
…
Benutze einen LogFormatter, um alle Werte am colorbar anzuzeigen. U.U. kann man auch noch das ticks keyword der colorbar Methode verwenden.
Anmerkung: colorbars können auch mit „extend= min|max|both“ erweitert werden.Allerdings klappt dies zurzeit nicht mit logarithmischen Werten.
Das Ergebnis…
31
map_demo_v05.py
Mehr Karten…
32
siehe http://matplotlib.org/basemap/users/examples.html
Vertikalschnitte
33
Vertikale Schnitte durch Modellfelder sind nützlich, um z.B. Austauschprozesse besser zu verstehen, oder um einen schnellen Überblick über die globale Verteilung von Variablen (Temperatur, Spurengaskonzentrationen etc.) zu bekommen.
Wir beginnen mit dem (gewünschten) Ergebnis und erläutern dann schrittweise den hierfür erstellten Code. Dieser enthält eine Menge an matplotlib Kniffen und mag daher als Fundgrube zur Lösung eigener Probleme dienen.
34
Verti
cal C
ross
Sec
tions Beginnen wir mit dem Hauptprogramm. Es besteht im Wesentlichen aus
zwei Funktionsaufrufen: getZMData zum Einlesen der Daten (aus einer netCDF Datei), und plotZM zur Darstellung des Vertikalschnitts.
Code zur Erzeugung von Vertikalschnitten
Zuvor wird der Dateiname spezifiziert und dazwischen wird ein Dictionary mit diversen Plot-Optionen definiert. Der Code funktioniert auch ohne Übergabe des plotOpt dictionaries, allerdings sieht der Plot dann nicht so schön aus.
Man beachte: während die getZMData Routine dafür ausgelegt ist, zonale Mittelwerte zurückzugeben (also Mittelwerte über alle longitudes), kann plotZM auch zur Anzeige einzelner Schnitte (allerdings immer mit Latitude als x Achse) benutzt werden. Die surfacePressure Option ist vor allem für diesen Fall vorgesehen.
35
Verti
cal C
ross
Sec
tions
Modulimport und Einlesen der Daten
ACHTUNG: Modell-abhängig!
Bedingte Indizierung
36
Verti
cal C
ross
Sec
tions
Darstellung des Zonalschnittes
Es kann gar nicht oft genug betont werden, wie wichtig eine gute (aber nicht zu ausführliche) Dokumentation ist!
37
Verti
cal C
ross
Sec
tions
Wir beginnen mit ein paar Basisdingen:• setze plotOpt auf ein leeres dictionary, falls keine Optionen übergeben
wurden (das erlaubt den Zugriff auf Elemente via get-Methode)• definiere Konstanten (hier nur labelFontSize)• erzeuge eine figure und das erste Koordinatensystem (ax1), in welches
geplottet wird• skaliere die Daten (lege eine Kopie an, damit die Ursprungsdaten nicht
überschrieben werden)
38
Verti
cal C
ross
Sec
tions
Das war schon der Hauptteil des eigentlichen Konturplots. Beachte folgendes:• das Auslesen der Kontur-Intervalle aus plotOpt erfolgt mit der get-
Methode. Wurde in plotOpt kein levels key definiert, wird der Default (20 linear ansteigende Intervalle zwischen min und max) benutzt.
• die Kontur-Intervalle müssen „vernünftig“ den Farben der Farbtabelle zugeordnet werden. Dies geschieht hier mit der BoundaryNorm, die am flexibelsten ist.
• die fill_between Methode wird benutzt, um die Region unterhalb des Bodendrucks auszublenden
• dem colorbar wird ein label hinzugefügt und die tick labels des colorbars werden auf die definierte Fontgröße gesetzt
39
Verti
cal C
ross
Sec
tions
Die Formatierung der linken y Achse ist noch relativ einfach. Wir benutzen einen LogLocator, um die tick labels festzulegen und verwenden dabei das subs keyword, um eine feinere Einteilung als Dekaden zu bekommen. Je nach Wertebereich (siehe topLevel keyword bei getZMData) werden mal mehr, mal weniger subs eingefügt.
Als Zahlenformatierung der pressure tick labels wählen wir %g. Dies schaltet automatisch auf Exponentialdarstellung um, wenn die Werte zu groß oder zu klein werden.
40
Verti
cal C
ross
Sec
tions
Nun beginnen wir mit der rechten Seite. Hier wollen wir optional ein kleines Nebenpanel anlegen, welches die Modellschichten anzeigt, falls das modelLevels keyword eien Liste von Druckwerten enthält. Dementsprechend werden die altitude tick labels entweder an der zweiten y Achse des Hauptplots (ax2), oder an dem Zusatzplot (axm) angezeigt.
Zunächst berechnen wir jedoch die Höhen der Modelschichten aus den Druckwerten und erzeugen eine Zwillingsachse (ax2). Sodann folgt ein bisschen Formatierung der x Achsenticks (Latitude).
Beachte, dass hier ax1.xaxis… stehen muss und diese Anweisungen nach dem twinx() Befehl auftauchen sollten – ansonsten geht es womöglich schief.
41
Verti
cal C
ross
Sec
tions
Hier erfolgt nun das Zeichnen der horizontalen Linien für die Modellschichten, falls gewünscht. Mittels fig.add_axes erzeugen wir ein weiteres Achsensystem, welches über sharey mit der (rechten) y Achse unseres Hauptsystems verbunden ist. Dadurch kann man den Plot später interaktiv zoomen und verschieben und der Konturplot ändert sich synchron mit der Anzeige der Modellschichten.
Wenn wir das Zusatzpanel anzeigen, schalten wir dessen x Achse auf unsichtbar und löschen die tick labels des ax2 Koordinatensystems. Die Ticklinien bleiben jedoch stehen (deshalb nicht einfach ax2.yaxis.set_visible(False)).
Zur Verschiebung der Achsenbeschriftung
42
Verti
cal C
ross
Sec
tions
Schließlich verwenden wir den soeben definierten Alias für die rechte Achse (axr), um die Formatierung der „Altitude“ Achse festzulegen:• mit dem MaxNLocator erzeugen wir im Allgemeinen sinnvoll gestaffelte
tick labels• yaxis.tick_right() zwingt die tick labels auf die rechte Seite (das wäre zwar
bei ax2 der default, bei axm aber nicht)• Auch bei der rechten Achse werden die tick labels wieder auf die
gewünschte Fontgröße gesetzt
Der vollständige Code steht unter ftp://sv02.meteo.uni-bonn.de/pub/maschu/python/codes/plot_vertical_cross_section.py
43
THEEND
Weitere Themen für die Zukunft:• Interpolation• Farb-Management• Grafische Benutzeroberflächen• Wissenschaftliche Datenauswertung• …
Bonus-Material
44
Wenigstens ein bisschen was zur Interpolation – ohne große Worte…