Das Modul matplotlib verfügt über eine fast unübersichtliche Vielzahl von Möglichkeiten physikalische Zusammenhänge im 2D- oder 3D-Raum zu visualisieren. Neben den üblichen statischen Darstellungen von mathematischen Funktionen in x-y-Koordinaten sind auch Animationen und interaktive Anwendungen implementierbar.
Ein Figure-Objekt legt den gesamten Zeichenbereich fest, in dem ein Funktionsplot eingefügt werden soll.
Ein Axes-Objekt ist zuständig für die Gestaltung des Koordinatensystems: Beschriftung der x,y-Achsen, Einfügen von beliebigen Text und Formeln mit der Latex-Notation usw.. In einem Figure-Objekt können mehrere Axes-Objekte eingebettet werden.
Mit der Axes-Methode axis([x1,x2,y1,y2])
kann man den Wertebereich des Koordinatensystems festlegen.
Das erste Beispiel zeigt, wie ein typischer Funktionsplot für eine 50 Hz-Wechselspannung erstellt werden kann.
\[u=\widehat{u} \cdot sin\left( 2\pi \cdot f\cdot t\right) \]
import numpy as np
import matplotlib.pyplot as plt
t=np.arange(0,20,0.001)
#Funktionsdefinitionen
Ueff=[230,230] #Daten für Effektivwert
u=325*np.sin(2*np.pi*50*t/1000.0)
#Plot darstellen
fig,ax=plt.subplots() #Objekte erzeugen
ax.plot(t,u,'b',lw=2,label="Momentanwert: u(t)") #Koordinaten berechnen
ax.plot([0,20],Ueff,'r--',label="Effektivwert: 230V")
ax.plot(5,325,'ro',label="Spitzenwert:325V")
ax.set_title("50 Hz Wechselspannung")
ax.set_ylabel("u(t) in V")
ax.set_xlabel("t in ms")
ax.legend(loc='best')
ax.grid(color='g',ls='dashed',lw='0.5')
fig.savefig("abb_02_01.svg")
plt.show() #Plot anzeigen
Mit der Methode plot(x,y,...)
werden die x-y-Koordinaten der Funktion berechnet und intern im Arbeitsspeicher (RAM) abgespeichert. Die Methode show()
bewirkt, dass der Funktionsplot auf dem Monitor angezeigt wird. Mit der Methode savefig(...)
kann der Plot in einem gewünschten Bildformat auf der Festplatte gespeichert werden.
Mit der Anweisung fig.add_subplot(projection='3d')
können 3D-Funktionsplots erstellt werden. Das Beispiel zeigt die Zustandsfläche für
\[p=f\left( T,V\right) =\frac{n\cdot R\cdot T}{V} \]
#3D-Funktionsplot.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
#p=n*R*T/V
def p(V,T):
T=T+273.15 #Umwandlung in K
n=1 #mol ideales Gas
R=8.314 #Gaskonstante J/(mol*K)
return 10*n*R*T/V
#Grafikbereich
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(projection='3d') #1
V=np.linspace(10,50,100) #Volumen in dm^3, dann p in hPas
T=np.linspace(0,200,100)
V,T=np.meshgrid(V,T) #2
#x,y,z
ax.plot_wireframe(V, T, p(V,T), rstride=10, cstride=10) #3
#Standardbedingungen Liter, °C, mbar
ax.plot(22.41, 0, 1013,'ro') #roten Punkt zeichen
ax.set(xlabel='V in Liter',ylabel='T in °C',zlabel='p in mbar')
plt.show()
#1: Das ax-Objekt enthält alle Eigenschaften, um einen 3D-Funktionsplot zu zeichnen.
#2: Die NumPy-Funktion meshgrid(...)
erzeugt ein Gitternetz von 100×100=10000 Punkten für die x-y-Ebene.
#3: Die Matplotlib-Methode plot_wireframe(...)
zeichnet die Funktion p=f(T,V).
Das dritte Beispiel zeigt den Einsatz des Sliders. Durch Verschieben des Slider-Knopfes können die Amplitude und die Frequenz der Sinusschwingung verändert werden.
#slider_demo.py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider,Button
#Eingaben
a0=5
f0=5
#Funktionsdefinitionen
def s(t):
return a0*np.sin(2*np.pi*f0*t)
#Änderungen abfragen
def update(val):
A = sldAmp.val
f = sldFreq.val
kurve.set_data(t,A*np.sin(2*np.pi*f*t))
#Zurücksetzen
def reset(event):
sldFreq.reset()
sldAmp.reset()
#Grafikbereich
fig, ax = plt.subplots()
ax.axis([0, 1, -10, 10])
fig.subplots_adjust(left=0.2,bottom=0.25)
t=np.linspace(0.0,1.0,200)
kurve, = ax.plot(t,s(t),lw=2,color='blue')
#Objekte für Steuerelemente platzieren
#linker Rand, unterer Rand, Breite, Höhe
xyAmp=fig.add_axes([0.25, 0.15, 0.65, 0.03])
xyFreq=fig.add_axes([0.25, 0.1, 0.65, 0.03])
xyReset=fig.add_axes([0.8,0.025,0.1,0.04])
#Objekte für Steuerelemente erzeugen
sldAmp=Slider(xyAmp,'Amplitude',1,10,valinit=a0,valstep=0.1) #1
sldFreq=Slider(xyFreq,'Frequenz',1,10,valinit=f0,valstep=0.1) #2
cmdReset=Button(xyReset,'Reset')
#Ereignisverarbeitung
sldAmp.on_changed(update) #3
sldFreq.on_changed(update) #4
cmdReset.on_clicked(reset)
plt.show()
In den Zeilen #1 und #2 werden zwei Sliderobjekte erzeugt. In den Zeilen #3 und #4 wird die Funktion update(...)
aufgerufen. Die Methode on_changed(update)
bewirkt, dass die Amplitude und die Frequenz geändert werden.
Das Programm besteht aus drei Teilen: 1. Eingaben, 2. Funktionsdefinitionen und 3. Grafikbereich.
Das nächste Beispiel zeigt die Anwendung der matplotlib-Methode FuncAnimation(...)
.
Eine Sinusschwingung bewegt sich von links nach rechts über den Bildschirm.
#Animation einer Sinusschwingung
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
def f(x,k):
return np.sin(x-k/20)
def v(k):
y.set_data(x,f(x,k))
return y,
#Grafikbereich
fig,ax=plt.subplots() #Erzeugen eines fig und ax Objektes
x=np.linspace(0,4*np.pi,200)
y, =ax.plot(x,f(x,0),lw=3,color='r')
#Animation
a=ani.FuncAnimation(fig,v,interval=20,blit=True) #1
plt.show()
Auffällig ist, dass man in #1 für die Animationsmethode ein Objekt erzeugen muss, obwohl dieses Objekt a
im späteren Programmverlauf nicht benötigt wird. Wenn dieses Objekt nicht erzeugt wird, dann wird die Animation auch nicht ausgeführt. Es wird ein statisches Bild auf dem Monitor angezeigt.
Im Buch (Python-Kurs,1. Auflage) müssen die Quelltexte entsprechend geändert werden:
Seite 191, Zeile 17
Seite 193, Zeile 29
Seite 195, Zeile 28