Dynamisches Diagramm mit matplotlib
Dass matplotlib recht cool ist wusste ich schon lange, aber dass es ein animation-Modul enthält war mir neu. Das musste ich selbstverständlich gleich ausprobieren.
Es finden sich diverse Beispiele im Internet, aber genau das was ich haben wollte war nicht dabei. Also blieb nur selbermachen.
Das Ziel: ein CSV mit einer Zeitreihe als Liniendiagramm darstellen und die Graphik periodisch mit den aktuellsten Daten neu zeichnen.
Dank matplotlib ist das gar nicht so schwer wenn man mal herausgefunden hat wie es geht. Am meisten Probleme machte die Zeitachse. Die Format-Einstellungen gehen beim clear() des Plots verloren und müssen immer wieder neu gesetzt werden.
Das Resultat
Zugegeben, das sieht nicht überwältigend aus. Für die paar Zeilen Code ist es aber schon ganz überzeugend.
Die zu Testzwecken frei erfundenen Daten verbessern den Eindruck natürlich auch nicht. Mit realen Daten und ein paar Punkten mehr dürfte es ganz vernünftig aussehen.
Der Code
# Import the required modules from datetime import datetime from matplotlib.animation import FuncAnimation from matplotlib import style import matplotlib.pyplot as plt import matplotlib.dates as dates import csv import sys # Set the style of the plot style.use( 'ggplot' ) # Create figure and axes fig, ax = plt.subplots() # Update the plot def update( frame ): try: xs = [] ys = [] # Read and parse the CSV file with open("data.csv",newline="") as file: reader = csv.reader( file ) for row in reader: if len(row) > 1: xs.append( datetime.strptime(row[0],"%H:%M") ) ys.append( float(row[1]) ) if len(xs) > 0: # Renew the plot ax.clear() ax.xaxis.set_major_formatter( dates.DateFormatter("%H:%M") ) ax.plot( xs, ys ) except: print( "Error: can't read file, ", sys.exc_info()[0] ) # Draw the initial graph update( None ) # Update the graph every twenty seconds ref = FuncAnimation( fig, update, interval=20000 ) # Show the plot plt.show()
Die Hauptarbeit wird von der Funktion update geleistet. Sie liest und parst das CSV, löscht den Graph und lässt ihn neu zeichnen.
Die Fehlerbehandlung ist eher simpel gehalten, weil es bei einem interaktiven Programm dieser Art auffallen müsste wenn nichts dargestellt wird.
Speziell ist die Abfrage ob es überhaupt Messwerte gibt. Wenn plot mit einer leeren Zeitachse aufgerufen wird, dann wirft die Funktion eine recht unverständliche Exception...
Zwei Angaben sind hart codiert die wohl besser Parameter wären: das Datenfile muss data.csv heissen, und die Refresh-Zeit ist auf 20 Sekunden festgelegt.
Die Daten
Das Bild oben wurde mit folgendem File erzeugt:
11:05,11 11:06,13 11:07,12 11:10,10 11:11,11 11:12,11 11:13,12 11:15,15 11:16,13 11:17,14
Der Aufbau ist trivial: Uhrzeit in der Form hh:mm, gefolgt vom Wert.
Wenn ein neuer Messwert dazukommt, wird das Diagramm nach spätestens 20 Sekunden aktualisiert. Für eine Temperaturmessung oder etwas ähnlich träges müsste das ausreichend sein.