Matplotlib

In [1]:
import numpy as np
import matplotlib.pyplot as plt

Damit die von Matplotlib erzeugten Bilder gleich im Notebook erscheinen, braucht man das folgende "magic command":

In [2]:
%matplotlib notebook

Es gibt auch die ältere Variante

%matplotlib inline

Geplottet werden prinzipiell Daten (Wertetabellen). Um eine Funktion zu plotten, muss man eine Wertetabelle herstellen, was mit numpy recht leicht geht. Aber fangen wir erst mal mit Daten an.

Einfache Plots

In [3]:
# ganz schnell mal ein Plot
y = [2, 4.3, 11, 4, 7]
plt.plot(y)
plt.show()

Wenn Sie dieses Notebook interaktiv abarbeiten, erscheint die obige Grafik mit einem Rahmen, der verschiedene Buttons enthält. Mit ihnen kann man z.B. zoomen oder die Grafik verschieben.

Mit dem Button rechts über der Grafik wird diese interaktive Funktionalität beendet.

Bitte drücken Sie immer diesen Button, bevor Sie die nächste Zelle abarbeiten. Sonst wird kein neues Plotfenster aufgemacht sondern der nächste Plot zum oben stehenden hinzugefügt.

In [4]:
# Ein paar Variationen:

y = [2, 4.3, 11, 4, 7]
plt.plot(y, color = 'red',   marker = 'o', linestyle = '')  # rote Datenpunkte
plt.plot(y, color = 'green', linestyle = '--')   # verbindende grüne gestrichelte Linie
plt.show()                                                

Bemerkungen:

  • Linestyles:

    • '--' (gestrichelt)
    • ':' (Punkte)
    • '-.' (Strich-Punkt)
    • '-' (durchgezogen, default)
    • '' (nix)
  • Marker: http://matplotlib.org/api/markers_api.html

  • Farben können u.a. auch RGB-Tupels: color = (0.23, 0.44, 0.99) oder Hex-Codes: color='#e30c03' sein.

  • Matplotlib hat eine Vielzahl von backends, also Ausgabemechanismen für Grafiken. In diesem notebook-Backend ist z.B. das abschliessende .show() unnötig. Ich schreibe es trotzdem, damit die Beispiele auch mit anderen backends funktionieren.

  • Im interaktiven Notebook stehen Buttons unter dem Plot. Man kann damit die Plots verschieben/zoomen und dann auch in der gewünschten Form als Grafik abspeichern.

In [5]:
# wenn die x-Werte nicht einfach 0,...,n sind:

x = [3,   4,  5, 6, 10]
y = [2, 4.3, 11, 4,  7]
plt.plot(x, y)
plt.show()
In [19]:
# noch ein paar Schnörkel: 
#
#  - Achsenbeschriftung mit xlabel, ylabel
#         (In allen Beschriftungs-Strings können LaTeX-Konstrukte 
#          wie $\sqrt{\alpha}$ verwendet werden)
#
#  - Kurzformen: '-r'  entspricht   linestyle='-', color='red'
#                '--b' entspricht   linestyle='--', color='red'
#
#  - Bereich der x,y-Achse festgelegt: .xlim([xmin,xmax])
#        (muss nach dem plot()-Befehl geschehen)
#
#  - Legende im Plot 
#
#  - Abspeichern als Grafikdatei
#

days = range(1,6)
Tmin = [2.3, 4.4,1.6,6.6,3.3]
Tmax = [12,13,8,7,8]

#plt.xlabel("Tage")
#plt.ylabel(r"Temperatur $\theta$")
#plt.plot(days, Tmin, '-r', linewidth = '5', label = "min. Temp.")
plt.plot(days, Tmin, '-r', linewidth=5,label="min. Temp.")
plt.plot(days, Tmax, '--b', label = "max. Temp")
plt.xlim([0, 6])
plt.ylim([0, 16])
plt.legend(loc = 'upper right')
#plt.savefig("fig1.png")
plt.show()

2D Punktmengen (Scatterplot)

In [26]:
# 2 Arrays mit je 600 normalverteilte Zufallszahlen 

n = 600
X = np.random.normal(0, 1 ,n)
Y = np.random.normal(0, 1, n)

# die 600 Punkte sollen nach ihrem Winkel eingefärbt werden 
Phi = np.arctan2(Y, X)

plt.scatter(X, Y, c = Phi)
plt.show()
In [27]:
# 2 Arrays mit je 600 normalverteilte Zufallszahlen 

n = 600
X = np.random.normal(0, 1 ,n)
Y = np.random.normal(0, 1, n)

# die 600 Punkte sollen nach ihrem Abstand zu (0,0) eingefärbt werden
D = np.sqrt(X**2 + Y**2)

plt.scatter(X, Y, c = -D)
plt.show()

Die saubere Variante

Bisher wurden alle Plots einfach in das gerade aktive Plotfenster gemalt. Für etwas kompliziertere Plots sollte man sich etwas mehr Mühe geben.

Grundprinzip:

  • plt.figure() erzeugt ein Abbildungs-Objekt, auf das man sich später bezieht: fig23=plt.figure()
  • Diesem Objekt fügt man ein oder mehrere Subplots hinzu: p1=fig23.add_subplot(111)

    Dabei bedeutet das Argument nmk, das dies der k-te Subplot in einem n x m-Raster ist.

  • Einem Subplot fügt man dann mittels .plot(), .scatter(),... eine oder mehrere Graphen hinzu: p1.plot(x,y)
  • Auf einem Subplot operieren dann Funktionen wie .set_xlim() oder .set_title().

Damit ist es auch nicht mehr nötig, die interaktiven Fenster um jeden Graph abzuschalten, wenn man einen neuen Graphen generieren will. Jeder .figure()-Aufruf erzeugt ein neues interaktives Fenster.

In [28]:
# 
fig1 = plt.figure()
subplot1 = fig1.add_subplot(111)
subplot1.plot([3,1,7,6], label = "tolle Messwerte")
subplot1.plot([2,4,2,6], label = 'Messwerte der anderen')
subplot1.set_ylim(0,10)
subplot1.set_title("So ein Quatsch")
subplot1.legend(loc = 'upper left')
fig1.show()
In [29]:
# Hier gibt es mal 2 Subplots in einem 1x2-Raster.
# ... und eine logarithmische Achse 
# ... und ein Grid (Hilfslinien)

fig2=plt.figure()
sp1=fig2.add_subplot(121)       # 1x2-raster, 1. subplot -> 121
sp2=fig2.add_subplot(122)       # 1x2-Raster, 2. Subplot -> 122 
sp1.plot([3,4,5,3,40], marker='o')
sp2.plot([1, 1.1, 3, 3.3, 4.4], [5,6,30,8,.0003], marker='x', linestyle='--')
sp2.plot([1, 1.1, 3, 3.3, 4.4], [7,9,0.3, 22, 6], marker='d', color='r')
sp2.set_yscale('log')
sp1.grid(True)
fig2.show()

Funktionsplots

Beim Erstellen von Funktionsplots helfen die vektorisierten Numpy-Funktionen.

Die Funktion linspace(Anfang, Ende, Anzahl der Punkte) erzeugt einen Vektor mit Stützstellen:

In [30]:
x=np.linspace(0, 6, 9)
print("x=", x)
print("x**2=", x**2)          
x= [ 0.    0.75  1.5   2.25  3.    3.75  4.5   5.25  6.  ]
x**2= [  0.       0.5625   2.25     5.0625   9.      14.0625  20.25    27.5625
  36.    ]

Die Funktionen aus Numpy, wie z.B. np.sin(), sind vektorisiert, d.h., sie wirken elementweise auf einen Array.

In [31]:
x = np.linspace(0,12,100)
y = np.sin(x)

fig3   = plt.figure()
splot3 = fig3.add_subplot(111)
splot3.plot(x,y)
splot3.plot(x, y**2, 'r')
fig3.show()