Home | Lehre | Videos | Texte | Vorträge | Software | Person | Impressum, Datenschutzerklärung |
Stand: 2024-04-30
mit vielen Formulierungen von ChatGPT 4
Matplotlib ist eine umfangreiche Bibliothek für die Erstellung von statischen, animierten und interaktiven Visualisierungen in Python. Sie bietet eine Vielzahl von Plot-Typen und Stilen und ist aufgrund ihrer Effizienz und Flexibilität besonders beliebt in der wissenschaftlichen und technischen Datenvisualisierung. Matplotlib ermöglicht es Benutzern, hochwertige Graphen, Charts und Figuren in verschiedenen Formaten zu erzeugen, und ist kompatibel mit einer breiten Palette von Betriebssystemen und Grafik-Backends.
Die Kernfunktionalität von Matplotlib basiert auf dem Erstellen von Figuren und Achsen, auf denen Benutzer ihre Daten visualisieren können. Die Bibliothek benutzt eine objektorientierte API, die es ermöglicht, komplexe Plots auf eine kontrollierbare und präzise Weise zu gestalten. Für schnelle und einfache Visualisierungen bietet Matplotlib auch eine prozedurale Schnittstelle, bekannt als Pyplot, die das Erstellen von Visualisierungen mit weniger Codezeilen unterstützt und dabei an die Funktionsweise von MATLAB® angelehnt ist.
Ein großer Vorteil von Matplotlib ist seine Erweiterbarkeit und Anpassbarkeit. Nutzer können das Aussehen von Graphen vollständig anpassen, indem sie Titel, Achsenbeschriftungen, Legenden und andere Stilelemente modifizieren, siehe die Beispiele auf den Cheatsheets und Handouts. Darüber hinaus können sie mit zusätzlichen Paketen wie Seaborn, das auf Matplotlib aufbaut, weiterführende statistische Visualisierungen erstellen. Diese Flexibilität macht Matplotlib zu einem unverzichtbaren Werkzeug für die Datenanalyse und -visualisierung in Python.
Natürlich muss Matplotlib vor der Arbeit damit in das virtuelle Environment installiert werden.
Es soll ein xy-Datensatz als Streudiagramm geplottet werden, dazu die Regressionsgerade samt deren Gleichung.
Zunächst importieren wir die benötigte Bibliothek. Hier wird das
Plot-Modul von matplotlib
unter dem kurzen Namen
plt
eingebunden, so dass seine Funktionen usw. Namen wie
plt.tu_was()
erhalten (Details später im Semester):
import matplotlib.pyplot as plt
Nun definieren wir eine Liste von x-Werten und eine Liste von y-Werten. Im wahren Leben kämen diese Daten aus einer Datei, aus einer Datenbank, aus dem Netz oder von Sensoren:
= [3.8, 3.9, 4.0, 4.2, 4.3]
x = [1.9, 3.5, 3.1, 4.6, 6.3] y
Als nächstes erstellen wir einen Scatterplot dieser Daten:
plt.scatter(x, y)
Nun fügen wir dem Diagramm einen Titel und Achsenbeschriftungen
hinzu; innerhalb der $...$
stehen mathematische Zeichen und
Formeln im LaTeX-Format:
'Scatterplot mit Regressionsgerade')
plt.title('Was auch immer $x$ ist')
plt.xlabel('Was auch immer $y$ ist') plt.ylabel(
Zuletzt zeigen wir das Diagramm an:
plt.show()
Das Program bleibt in diesem plt.show()
hängen, bis man
das Fensterchen mit dem Diagramm schließt. (Es gibt auch einen Weg,
Matplotlib sofort weiterarbeiten zu lassen, statt dass es auf das
Schließen des Fensters wartet.)
Um nun noch eine Regressionsgerade durch den Scatterplot zu legen,
verwenden wir die Funktion linregress
der Bibliothek SciPy.
Beachte, dass diese eine Funktion hier fünf Werte
zurückliefert, von denen wir nur die ersten beiden speichern:
# an den Anfang des Programms:
import scipy.stats as stats
# vor dem show():
= stats.linregress(x, y) steigung, achsenabschnitt, _, _, _
Diese Linie können wir dann über den Scatterplot zeichnen. Die
Funktion plot
erwartet eine Liste an x-Werten (hier sind es nur zwei
Stück) und eine Liste dazugehöriger y-Werte. Einer der vielen weiteren
Parameter dieser Funktion, die man per Namen angeben kann, ist
color
:
# vor dem show():
3.8, 4.3], [steigung * 3.8 + achsenabschnitt, steigung * 4.3 + achsenabschnitt], color='red') plt.plot([
Aufgabe: Schreiben Sie die obige Zeile klarer und robuster, indem Sie die x-Werte aus den Daten gewinnen und die y-Werte mit einer selbstdefinierten Funktionen daraus erzeugen!
Und nun setzen wir noch mittels LaTeX in einem f-String die Gleichung der Regressionsgerade in das Diagramm:
# vor dem show():
4.05, 3.5, f'$y = {steigung:.2f}x + {achsenabschnitt:.2f}$', fontsize=12, color='red') plt.text(
Dies ist eine Ergänzung für Hartgesottene.
Schöner ist das Ganze, wenn die Zahlen in deutscher statt amerikanischer Schreibweise erscheinen (Dezimalkomma statt Dezimalpunkt, Tausender usw. mit Punkt statt mit Komma). Das geht so:
# am Anfang des Programms
import locale
# vor dem ersten Plot-Befehl
'axes.formatter.use_locale'] = 'True'
plt.rcParams[# unten im Programm
'de_DE.UTF-8')
locale.setlocale(locale.LC_ALL, 4.05, 3.5, f'$y = {steigung:.2n}x {"+" if achsenabschnitt >= 0 else "-"}{abs(achsenabschnitt):.2n}$'.replace(',', '{,}'), fontsize=12, color='red') plt.text(
Das Einstellen von axes.formatter.use_locale
bewirkt,
dass für die Zahlen an den Koordinatenachsen die locale
,
also die regionale Einstellung, berücksichtigt wird. Das n
in der Formatangabe im f-String macht Entsprechendes für die Umwandlung
von Zahlen in Zeichenketten. Außerdem sorgen wir noch dafür, dass ein
negativer achsenabschnitt
nicht mit Pluszeichen (wörtlich
im f-String angegeben) und Minuszeichen (von der Zahl)
erscheint.
Normalerweise ruft man setlocale
ganz am Anfang des
Programms auf; allerdings setzt Matplotlib diese Einstellung zurück. Und
noch ein weiterer Trick: LaTeX interpretiert Zahlen mit Dezimalkomma
darin als Listen von Zahlen und lässt deshalb nach dem Komma eine Lücke.
Um das zu verhindern, folgt dem f-String noch ein replace
,
das das Komma durch {,}
ersetzt, wie es in LaTeX üblich
ist.
Angenommen, wir haben noch Angaben zu den Unsicherheiten der y-Werte:
= [1.2, 0.7, 1.4, 0.9, 0.8] y_error
Dann können wir passende Fehlerbalken zeichnen lassen, indem wir
statt plot.scatter
dies aufrufen:
=y_error, fmt='o', capsize=5) plt.errorbar(x, y, yerr
Nun müsste man noch die unterschiedlichen Fehlerbalken bei der Berechnung der Regressionsgeraden berücksichtigen und statt einer einzigen Regressionsgeraden ein Konfidenzband zeichnen. Fragen Sie die KI, wie das geht.
Wir lassen die Umrisse der Kontinente auf einer per Maus drehbaren Kugel zeichnen.
Laden Sie dazu die Daten von Natural
Earth und legen Sie die Dateien ne_110m_land.shp
und
ne_110m_land.shx
aus dem heruntergeladenen Zip-Archiv an
eine Stelle, wo Sie sie wiederfinden.
Um solche Shapefile-Dateien zu lesen, ist noch die Bibliothek Geopandas zu installieren. Wir benötigen auch die Bibliothek NumPy (Numerical Python), die effizient mit großen Mengen an Zahlen (Vektoren, Matrizen usw.) umgeht. Numpy ist aber schon automatisch mit Matplotlib installiert worden.
Der Anfang des Programms ist damit:
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
Wir erzeugen zum Test ein Diagramm mit einem 3D-Plot eines Dreiecks. Die Eckpunkte sind (0, 0, 0), (1, 0, 0) und (0, 1, 0). Um alle drei Linien zu zeichnen, ist der erste Eckpunkt wiederholt:
= plt.figure()
fig = fig.add_subplot(projection='3d')
ax
= [0, 1, 0, 0]
x = [0, 0, 1, 0]
y = [0, 0, 0, 0]
z
ax.plot(x, y, z)
plt.show()
Nun können wir die Datei mit den Geodaten einlesen und die Umrisse der Kontinente plotten:
# Hier den Pfad zur Ihrer shp-Datei nehmen:
= gpd.read_file('ne_110m_land.shp')
kontinente
for poly in kontinente.geometry:
if poly.geom_type == 'Polygon':
= poly.exterior.coords.xy
längengrade, breitengrade = np.radians(längengrade)
phis = 0.5 * np.pi - np.radians(breitengrade)
thetas = np.sin(thetas) * np.cos(phis)
x = np.sin(thetas) * np.sin(phis)
y = np.cos(thetas)
z ='k') ax.plot(x, y, z, color
Hier wird der Effizenz halber immer mit allen Eckpunkten eines
Polygons auf einmal gerechnet. Die Variablen im if
sind
dazu allesamt Arrays (wirklich Arrays und nicht die grundlegenden Listen
von Python). Die Längengrad-Angaben aller Punkte eines Polygons werden
auf einen Schlag von Winkelgrad nach Radiant umgerechnet, von allen
Winkeln ϕ wird auf einen
Schlag der Cosinus genommen, die jeweiligen Werte von sin (θ) und cos (ϕ) werden für alle Punkte auf
einen Schlag multipliziert usw. Sehen Sie sich im Debugger die Werte
von längengrade
usw. an.
Nun fehlt noch die Kugel. Sie wird nicht mit Linien gezeichnet, sondern mit gefüllten Vierecken. Hier ein Beispiel für ein einziges Viereck:
= np.array([[1, 2], [3, 4]])
x = np.array([[2, 2], [4, 5]])
y = np.array([[0, 0], [0, 0]])
z ax.plot_surface(x, y, z)
Die Funktion plot_surface
verlangt die Koordinaten im
Raster über die gesamte Fläche. Also müssen x
,
y
und z
jeweils zweidimensionale Arrays sein.
Das Array für y
im Beispiel oben ist dieses:
2 | 2 |
4 | 5 |
Für die Erdkugel gehen wir den Winkel ϕ ∈ [0, 2π] und den Winkel
θ ∈ [0, π] der
sphärischen Koordinaten jeweils in (zum Beispiel) 100 Schritten durch.
Dazu dient die Funktion linspace
. Daraus bildet
meshgrid
zweidimensionale Arrays, die die Fläche im Raster
durchlaufen. Diese Arrays werden dann von den sphärischen Koordinaten
auf kartesische Koordinaten x,
y und z umgerechnet:
= np.linspace(0, 2*np.pi, 100)
phis = np.linspace(0, np.pi, 100)
thetas = np.meshgrid(phis, thetas)
phis_all, thetas_all = np.cos(phis_all) * np.sin(thetas_all)
x = np.sin(phis_all) * np.sin(thetas_all)
y = np.cos(thetas_all)
z ='b', alpha=0.2) ax.plot_surface(x, y, z, color