Grafische Ausgaben
Es gibt sehr viele Varianten für die grafische Ausgabe von Zahlenwerten. Im folgenden wird die
Bibliothek mathplotlib
verwendet. In der Regel funktionieren die Beispiele nicht über den
Button "Python Online", weshalb dieser hier nicht zu sehen ist. Die Beispiele
sollten daher über den Button "Copy" kopiert werden und in der
eigenen grafischen Umgebung idle3
, Thonny
, etc., ausgeführt werden.
Erste Versuche
Einführung in matplotlib
# Hinweis # ------- file: myplot.py ------ import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 10, 100) plt.plot(x, np.sin(x)) plt.plot(x, np.cos(x)) plt.show()
# Hinweis import numpy as np import matplotlib.pyplot as plt def make_plot(p, num_pts=40): k = np.arange(num_pts) # [ 0 1 2 3 ... num_pts-1 ] z = (1 - 1/p)**k # [ z0 z1 z2 ... znum_pts-1 ] plt.axes().set_aspect(1) plt.plot(z.real, z.imag) plt.grid() plt.title(f"$x^{{ {p.real} + {p.imag}i }}$") plt.show() make_plot(0.53 + 0.4j) make_plot(0.50 + 0.3j,100) make_plot(0.48 + 0.3j,100)
# Hinweis import matplotlib.pyplot as plt import numpy as np; np.random.seed(121) fig, ax = plt.subplots() def histoPlot(ax): ax.hist(np.random.normal(0, 1, 1000), bins=100) histoPlot(ax) histoPlot(ax) histoPlot(ax) plt.show()
# Hinweis import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np def getdata(): return np.random.uniform(0,1,10) fig, axe = plt.subplots(5, 2) row=[0,0,1,1,2,2,3,3,4,4] col=[0,1,0,1,0,1,0,1,0,1] for im in range(10): r=row[im] c=col[im] axe[r][c].scatter(getdata(), getdata()) # trial 1 -> tried and it works, no need for trial 2 plt.show() plt.savefig('figure1.pdf')
Einführung in matplotlib
Das Prinzip
Sehr häufig müssen einfache oder auch komplexe mathematische Funktionen der Art $y=f(x)$ dargestellt
werden.
In matplotlib
wird zuerst die Variable graph
als eine Instanz der Klasse plt.figure
erstellt. Sie kann als Container für alle folgenden Objekte, die zum Graphen gehören, betrachtet werden.
Die üblichen Achsen als eine Instanz der Klasse plt.axes
definieren die sogenannte Bounding Box, sowie die
"ticks" und "label" der Achsen.
Nach Festlegung der Achsen kann mit ax.plot
eine Funktion graphisch dargestellt werden.
# Hinweis import matplotlib.pyplot as plt import numpy as np graph = plt.figure() achsen = plt.axes() x = np.linspace(0, 10, 1000) achsen.plot(x, np.sin(x));
Die folgende Abbildung zeigt die sogenannte Schwebung, die man beim Stimmen von zwei gleichen Instrumenten benutzen kann.
# Hinweis import matplotlib.pyplot as plt import numpy as np graph = plt.figure() achsen = plt.axes() x = np.linspace(0, 40*np.pi, 3000) achsen.plot(x, np.sin(x)+np.sin(1.1*x));
Es können beliebig viele Funktionen in ein und dasselbe Koordinatensystem eingetragen werden:
# Hinweis import matplotlib.pyplot as plt import numpy as np graph = plt.figure() achsen = plt.axes() x = np.linspace(0, 40*np.pi, 3000) achsen.plot(x, np.sin(x)+np.sin(1.1*x)); achsen.plot(x, np.sin(x)+np.sin(1.05*x)); plt.show()
Optionen
Farbe und Linienstil
Zu den üblichen Einstellungen gehören Linienfarben und -stile, was
über zusätzliche Argumente von plt.plot(...)
erfolgt. Für die Farbe das Schlüsselwort color
,
verschiedene Farbdefinitionen möglich sind.
# Hinweis import matplotlib.pyplot as plt import numpy as np graph = plt.figure() achsen = plt.axes() x = np.linspace(0, 40*np.pi, 3000) achsen.plot(x, np.sin(x - 0), color='blue') # specify color by name achsen.plot(x, np.sin(x - 1), color='g') # short color code (rgbcmyk) achsen.plot(x, np.sin(x - 2), color='0.75') # Grayscale between 0 and 1 achsen.plot(x, np.sin(x - 3), color='#FFDD44') # Hex code (RRGGBB from 00 to FF) achsen.plot(x, np.sin(x - 4), color=(1.0,0.2,0.3)) # RGB tuple, values 0 to 1 achsen.plot(x, np.sin(x - 5), color='chartreuse'); # all HTML color names supported
Die Linienstile können mit linestyle=...
in Lang- oder Kurzform angegeben werden,
jeweils in Form von Zeichenketten:
solid
oder -
dashed
oder --
dashdot
oder -.
dotted
oder :
linestyle='dashdot'
oder linestyle='-.'
. Linienfarbe und Linienstil können
auch zusammen angegegen werden, wenn für die Farbe ebenfalls die Kurzform (rgbcmyk, (Red/Green/Blue, Cyan/Magenta/Yellow/blacK) genutzt wird:
'-g'
# solid und green'--y'
# dashed und yellow'-.k'
# dashdot und black ':b'
# dotted und blueAchsenbereich
Ohne Angabe eines Bereiches übernimmt mathlotlib
in Abhängigkeit der x-Werte die sinnvolle Einteilung der Achsen.
Mit plt.xlim()
und plt.ylim()
können die BEreiche individuell festgelegt werden:
# Hinweis import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 4*np.pi, 1000) plt.plot(x, np.sin(x)) plt.xlim(-1, 11) plt.ylim(-1.5, 1.5)
Etwas verwirrend ist die Tatsache, dass sich gleiches auch über die Funktion plt.axis([...])
erreichen lässt.
# Hinweis import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 4*np.pi, 1000) plt.plot(x, np.sin(x)) plt.axis([-1, 11, -1.5, 1.5]);
Mit plt.axis('tight')
kann eine Achseneinteilung gewählt werden, die der Bounding Box entspricht, also den kleinst-möglichen
Bereich auswählt. Mit plt.axis('equal')
kann man eine proportionale Einteilung erreichen. Eine Längeneinheit auf der x-Achse
entspricht dann bei einer trigonometrischen Funktion ca. 57°=180°/π.
Beschriftungen (Label)
Für die Beschriftung der Achsen und einem allgemeinen Titel gibt es eigene Funktionen, wohingegen eine Legende über
die Optionen mit label=...
definiert wird:
# Hinweis import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 4*np.pi, 1000) plt.grid() plt.title("Eine Sinuskurve $y=\sin(x)$") plt.xlabel("x in rad"); plt.ylabel("$2\sin(x) / 2\cos(x)$") plt.plot(x, 2*np.sin(x), '--r', label='$2\sin(x)$') plt.plot(x, 2*np.cos(x), ':b', label='$2\cos(x)$') plt.axis('equal') plt.legend();
Anstelle der verschiedenen Funktionen, die hier Matlab-like sind, kann auch mit der Methode ax.set(...)
gearbeitet werden.
# Hinweis import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 4*np.pi, 1000) plt.grid() ax = plt.axes(2) ax1.plot(x, np.sin(x)) ax1.set(xlim=(0, 10), ylim=(-2, 2), xlabel='x', ylabel='sin(x)', title='A Simple Plot'); ax2.plot(x, np.cos(x)) ax1.set(xlim=(0, 10), ylim=(-2, 2), xlabel='x', ylabel='cos(x)');
Weitere Möglichkeiten für Legenden gibt es im Data Science Handbook.
Punktdiagramme (Scatter plots)
Die Daten werden hierbei als einzelne Koordinatenpunkte aufgefasst, die im Gegensatz zum Liniendiagramm nicht verbunden werden. Die Punkte können mit einem Symbol, im einfachsten Fall mit einem kleinen ausgefüllten schwarzen Kreis markiert werden.# Hinweis import matplotlib.pyplot as plt import numpy as np plt.style.use('seaborn-whitegrid') fig, axs = plt.subplots(2, figsize=(10, 10)) x = np.linspace(0, 10, 30) y = np.sin(x) axs[0].plot(x, y, 'o', color='black') axs[0].plot(x, y, '--', color='red') ng = np.random.RandomState(0) phase = 0 for marker in ['o', '.', ',', 'x', '+', 'v', '^', '<', '>', 's', 'd']: axs[1].plot(x, np.sin(x+phase), marker, label="marker='{0}'".format(marker)) phase += 0.2 plt.legend(numpoints=2, frameon=True) plt.xlim(0, 4*np.pi); plt.show()
Sämtliche Randbedingungen für die Punkte können indivisuelle eingestellt werden, beispielsweise:
# Hinweis import matplotlib.pyplot as plt import numpy as np plt.style.use('seaborn-whitegrid') x = np.linspace(0, 10, 30) y = np.sin(x) plt.plot(x, y, '-p', color='gray', markersize=15, linewidth=4, markerfacecolor='red', markeredgecolor='gray', markeredgewidth=2) plt.ylim(-1.2, 1.2); plt.show()
Es existiert auch eine Funktion plt.scatter()
, welche eine einfachere Handhabung ermöglicht, jedoch bei sehr
großen Datenmengen nicht so effizient arbeitet.
# Hinweis import matplotlib.pyplot as plt import numpy as np plt.style.use('seaborn-whitegrid') rng = np.random.RandomState(0) x = rng.randn(100) y = rng.randn(100) colors = rng.rand(100) sizes = 1000 * rng.rand(100) plt.scatter(x, y, c=colors, s=sizes, alpha=0.3, cmap='viridis') plt.colorbar(); # show color scale plt.show()
Alle weiteren Optionen kann man der Dokumentation von pyplot
entnehmen: https://matplotlib.org/api/pyplot_api.html
Weitere Möglichkeiten
Background Code
# Hinweis from PIL import Image from apscheduler.schedulers.background import BackgroundScheduler w, h, zoom = 1920, 1080, 1 # creating the new image in RGB mode bitmap = Image.new("RGB", (w, h), "white") pix = bitmap.load() cX, cY = -0.7, 0.27015 moveX, moveY = 0.0, 0.0 maxIter = 255 def dots(): print(".",end="") #Kontrolle = BackgroundScheduler() #Kontrolle.add_job(dots, 'interval', seconds=1) #Kontrolle.start() for x in range(w): for y in range(h): zx = 1.5 * (x - w / 2) / (0.5 * zoom * w) + moveX zy = 1.0 * (y - h / 2) / (0.5 * zoom * h) + moveY i = maxIter while zx * zx + zy * zy < 4 and i > 1: tmp = zx * zx - zy * zy + cX zy, zx = 2.0 * zx * zy + cY, tmp i -= 1 # convert byte to RGB (3 bytes) RedGreenBlue pix[x, y] = (i << 21) + (i << 10) + i * 8 #Kontrolle.shutdown() bitmap.show()
Nächste Einheit: 08 Anwendungen