Matplotlib-Tutorial


Einführung

Matplotlib-Beispielgraph: Konturplot mit Triangulation

Matplotlib ist eine Bibliothek zum Plotten wie GNUplot. Der Hauptvorteil gegenüber GNUplot ist die Tatsache, dass es sich bei Matplotlib um ein Python-Modul handelt. Aufgrund des wachsenden Interesses an der Programmiersprache Python steigt auch die Popularität von Matplotlib kontinuierlich.

Ein anderer Grund für die Attraktivität von Matplotlib liegt in der Tatsache, dass es weithin als perfekte Alternative für MATLAB angesehen wird, wenn es in Verbindung mit Numpy und Scipy benutzt wird. Während es sich bei MATLAB um kostspielige Closed-Source-Software handelt, ist die Software von Matplotlib frei, kostenlos und quelloffen. Außerdem kann in Matplotlib objektorientiert programmiert werden. Es kann auch in allgemeinen GUI wie wxPython, Qt, and GTK+ verwendet werden. Mit der "pylab"-Erweiterung wird die Möglichkeit geboten noch MATLAB-ähnlicher zu programmieren. Davon wird jedoch im Allgemeinen abgeraten, da dies zu einem unsauberen Programmierstil führt, auch wenn es dadurch MATLAB-Nutzern extrem leicht gemacht wird zu wechseln.

Mittels Matplotlib kann man Diagramme und Darstellungen in verschiedenen Formaten erzeugen, die man dann in Veröffentlichungen verwenden kann.

Eine andere Besonderheit besteht in der steilen Lernkurve, was sich darin zeigt, dass die Benutzerinnen und Benutzer sehr schnelle Fortschritte bei der Einarbeitung machen. Auf der offiziellen Webseite steht dazu Folgendes: "matplotlib tries to make easy things easy and hard things possible. You can generate plots, histograms, power spectra, bar charts, errorcharts, scatterplots, etc, with just a few lines of code." (Matplotlib versucht Einfaches einfach und Schweres möglich zu machen. Man kann mit nur wenigen Codezeilen Plots, Histogramme, Leistungsspektren, Balkendiagramme, Fehlerdiagramme, Streudiagramme / Punktwolken, und so weiter erzeugen.


Ein erstes Beispiel

Wir werden mit einem einfachen Graphen beginnen, so einfach, dass es nicht mehr einfacher geht. Ein Graph in Matplotlib ist eine zwei- oder dreidimensionale Zeichnung die mit Hilfe von Punkten, Kurven, Balken oder anderem einen Zusammenhang herstellt. Es gibt zwei Achsen: Die horizontale X-Achse für die unabhängigen Werte und die vertikale y-Achse für die abhängigen Werte.

Wir werden im Folgenden das Untermodul 'pyplot' verwenden. pyplot stellt eine prozedurale Schnittstelle zur objektorientierten Plot-Bibliothek von Matplotlib zur Verfügung. Die Kommandos von pyplot sind so gewählt, dass sie sowohl in den Namen als auch in ihren Argumenten MATLAB ähnlich sind.

Es ist allgemein üblich matplotlib.pyplot zu plt umzunennen. In unserem ersten Beispiel werden wir die plot-Funktion von pyplot benutzen. Wir übergeben an die plot-Funktion eine Liste von Werten. plot benutzt die Werte dieser Liste als y-Werte. Die Indizes dieser Liste werden automatisch als x-Werte genommen.

Das Kommando %matplotlib inline macht nur Sinn, wenn man mit "ipython3 notebook" arbeitet. Es sorgt dafür, dass die Graphen innerhalb des Dokumentes und nicht als eigenes Fenster dargestellt werden.

%matplotlib inline
import matplotlib.pyplot as plt
plt.plot([-1, -4.5, 16, 23])
plt.show()

Wir sehen einen zusammenhängenden Graphen, obwohl wir nur diskrete Werte für Y zur Verfügung gestellt hatten. Indem wir einen Formatstring beim Funktionsaufruf mitübergeben, können wir einen Graphen mit diskreten Werten erzeugen, in unserem Fall mit blauen Vollkreisen. Der Formatstring definiert, wie die diskreten Punkte dazustellen sind.

import matplotlib.pyplot as plt
plt.plot([-1, -4.5, 16, 23], "ob")
plt.show()



Der Format-Parameter von pyplot.plot

In unserem vorigen Beispiel hatten wie "ob" als Formatparameter genutzt. Er besteht aus zwei Zeichen. Das erste definiert den Linienstil oder die Darstellung der diskreten Werte, die Markierungen (englisch 'markers'). Mit dem zweiten Zeichen wählt man die Farbe für den Graphen aus. Die Reihenfolge der beiden Zeichen hätte aber auch umgekehrt sein können, d.h. wir hätten auch "bo" schreiben können. Falls kein Formatparameter angegeben wird, wie es in unserem ersten Beispiel der Fall war, wird "b-" als Defaultwert benutzt, d.h. eine durchgehende blaue Linie.

Die folgenden Zeichen werden in einem Formatstring akzeptiert um den Linienstil oder die Marker zu steuern:

=============================================
Zeichen         Beschreibung
=============================================
'-'             durchgezogende Linie
'--'            gestrichelte Linie
'-.'            Strichpunkt-Linie
':'             punktierte Linie
'.'             Punkt-Marker
','             Pixel-Marker
'o'             Kreis-Marker
'v'             Dreiecks-Marker, Spitze nach unten
'^'             Dreiecks-Marker, Spitze nach oben
'<'             Dreiecks-Marker, Spitze nach links
'>'             Dreiecks-Marker, Spitze nach rechs
'1'             tri-runter-Marker
'2'             tri-hoch-Marker
'3'             tri-links Marker
'4'             tri-rechts Marker
's'             quadratischer Marker
'p'             fünfeckiger Marker
'*'             Stern-Marker
'h'             Sechseck-Marker1
'H'             Sechseck-Marker2
'+'             Plus-Marker
'x'             x.Marker
'D'             rautenförmiger Marker
'd'             dünner rautenförmiger Markerr
'|'             Marker in Form einer vertikalen Linie
'_'             Marker in Form einer horizontalen Linie
===============================================

Die folgenden Farbabkürzungen sind möglich:

==================
Zeichen     Farbe
==================
'b'         blau
'g'         grün
'r'         rot
'c'         cyan
'm'         magenta
'y'         gelb
'k'         schwarz
'w'         weiß
==================

Wie einige sicherlich schon vermutet haben, kann man auch X-Werte an die Plot-Funktion übergeben. Im folgenden Beispiel übergeben wir eine Liste mit den Vielfachen von 3 bis 21 und der Zahl 0 als X-Werte an plot:

import matplotlib.pyplot as plt
# die X-Werte:
days = list(range(0, 22, 3))
print(days)
# die Y-Werte:
celsius_values = [25.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
plt.plot(days, celsius_values)
plt.show()
[0, 3, 6, 9, 12, 15, 18, 21]

... und das ganze wieder mit diskreten Werten:

plt.plot(days, celsius_values, 'bo')
plt.show()
[0, 3, 6, 9, 12, 15, 18, 21]


Bezeichnungen für die Achsen

Wir können das Aussehen unseres Graphen verbessern, indem wir die Achsen mit Bezeichnungen versehen. Dazu benutzen wir die ylabel- und xlabel-Funktionen von pyplot.

import matplotlib.pyplot as plt
days = list(range(1,9))
celsius_values = [25.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
plt.plot(days, celsius_values)
plt.xlabel('Day')
plt.ylabel('Degrees Celsius')
plt.show()

Wir können eine beliebige Anzahl von (x, y, fmt)-Gruppen in einer Plot-Funktion spezifizieren. Im folgenden Beispiel benutzen wir zwei verschiedene Listen mit Y-Werten:

import matplotlib.pyplot as plt
days = list(range(1,9))
celsius_min = [19.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
celsius_max = [24.8, 28.9, 31.3, 33.0, 34.9, 35.6, 38.4, 39.2]
plt.xlabel('Day')
plt.ylabel('Degrees Celsius')
plt.plot(days, celsius_min,
         days, celsius_min, "oy",
         days, celsius_max, 
         days, celsius_max, "or")
plt.show()


Abfragen and Ändern des Wertebereichs der Achsen

Mit der Funktion 'axis' können wir den Wertebereich einer Achse abfragen und ändern. Ruft man 'axis' ohne Argumente auf, liefert sie den aktuellen Wertebereich einer Achse zurück:

import matplotlib.pyplot as plt
days = list(range(1,9))
celsius_min = [19.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
celsius_max = [24.8, 28.9, 31.3, 33.0, 34.9, 35.6, 38.4, 39.2]
plt.xlabel('Day')
plt.ylabel('Degrees Celsius')
plt.plot(days, celsius_min,
         days, celsius_min, "oy",
         days, celsius_max, 
         days, celsius_max, "or")
print("The current limits for the axes are:")        
print(plt.axis())
print("We set the axes to the following values:")
xmin, xmax, ymin, ymax = 0, 10, 14, 45
print(xmin, xmax, ymin, ymax)
plt.axis([xmin, xmax, ymin, ymax])
plt.show()
The current limits for the axes are:
(1.0, 8.0, 15.0, 40.0)
We set the axes to the following values:
0 10 14 45
import matplotlib.pyplot as plt
days = list(range(1,9))
celsius_min = [19.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
celsius_max = [24.8, 28.9, 31.3, 33.0, 34.9, 35.6, 38.4, 39.2]
plt.xlabel('Day')
plt.ylabel('Degrees Celsius')
plt.plot(days, celsius_min,
         days, celsius_min, "oy",
         days, celsius_max, 
         days, celsius_max, "or")
plt.axis([0, 10, 18, 41])
plt.show()

"linspace" zur Definition von X-Werten

Im folgenden Beispiel werden wir die Numpy-Funktion 'linspace' verwenden. 'linspace' wird dazu benutzt gleichmäßig verteile Werte innerhalb eines spezifizierten Intervalls zu erzeugen. Wir haben linspace ausführlich in unserem Numpy-Tutorial behandelt.

import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0, 2 * np.pi, 50, endpoint=True)
F = np.sin(X)
plt.plot(X,F)
startx, endx = -0.1, 2*np.pi + 0.1
starty, endy = -1.1, 1.1
plt.axis([startx, endx, starty, endy])
plt.show()
import matplotlib.pyplot as plt
X = np.linspace(-2 * np.pi, 2 * np.pi, 50, endpoint=True)
F1 = 3 * np.sin(X)
F2 = np.sin(2*X)
F3 = 0.3 * np.sin(X)
startx, endx = -2 * np.pi - 0.1, 2*np.pi + 0.1
starty, endy = -3.1, 3.1
plt.axis([startx, endx, starty, endy])
plt.plot(X,F1)
plt.plot(X,F2)
plt.plot(X,F3)
plt.show()

Das nächste Beispiel ist im Prinzip nichts Neues. Wir fügen lediglich zwei weitere Plots mit diskreten Punkten hinzu:

import matplotlib.pyplot as plt
X = np.linspace(-2 * np.pi, 2 * np.pi, 50, endpoint=True)
F1 = 3 * np.sin(X)
F2 = np.sin(2*X)
F3 = 0.3 * np.sin(X)
startx, endx = -2 * np.pi - 0.1, 2*np.pi + 0.1
starty, endy = -3.1, 3.1
plt.axis([startx, endx, starty, endy])
plt.plot(X,F1)
plt.plot(X,F2)
plt.plot(X,F3)
plt.plot(X, F1, 'ro')
plt.plot(X, F2, 'bx')
plt.show()


Linienstil ändern

Der Linienstil eines Plots kann durch die Parameter 'linestyle' oder 'ls' der Plot-Funktion beeinflusst werden. Sie können auf einen der folgenden Werte gesetzt werden:

'-', '--', '-.', ':', 'None', ' ', ''

Wir können mit 'linewidth', wie der Name impliziert, die Lienienstärke oder Liniendicke setzen:

import matplotlib.pyplot as plt
X = np.linspace(0, 2 * np.pi, 50, endpoint=True)
F1 = 3 * np.sin(X)
F2 = np.sin(2*X)
F3 = 0.3 * np.sin(X)
F4 = np.cos(X)
plt.plot(X, F1, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, F2, color="red", linewidth=1.5, linestyle="--")
plt.plot(X, F3, color="green", linewidth=2, linestyle=":")
plt.plot(X, F4, color="grey", linewidth=2, linestyle="-.")
plt.show()



Regionen mit einfärben

Mit der pyplot-Funktion fill_between ist es möglich Flächen zwischen Kurven oder Achsen zu schraffieren oder einzufärben. Im folgenden Beispiel füllen wir die Flächen zwischen der X-Achse und dem Graph der Funktion sin(2*X):

import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
plt.plot (X, Y, color='blue', alpha=1.00)
plt.fill_between(X, 0, Y, color='blue', alpha=.1)
plt.show()

Die allgemeine Syntax von fill_between:

fill_between(x, y1, y2=0, where=None, interpolate=False, **kwargs)

Die Parameter von fill_between:

Parameter Bedeutung
x Ein Array mit N Elementen mit X-Werten
y1 Ein Array mit N Elementen (oder ein Skalar) von Y-Daten
y2 Ein Array mit N Elementen (oder ein Skalar) von Y-Daten
where Wenn auf None gesetzt, wird per Default alles gefüllt. Wenn es nicht None gesetzt wird, so wird ein numpy boolean-Array erwartet mit N Elementen. Es werden nur dann die Regionen eingefärbt, bei denen where==True ist.
interpolate Wenn True, so wird zwischen zwei Linien interpoliert um den genauen Schnittpunktes zu finden. Andernfalls werden die Start- und End- Werte nur als explizite Werte auf der Region erscheinen.
kwargs Schlüsselwort-Argument, die an PolyCollection übergeben werden.
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
plt.plot (X, Y, color='blue', alpha=1.00)
plt.fill_between(X, Y, 1, color='blue', alpha=.1)
plt.show()
In [ ]: