2017-07-24 8 views
0

Ich lese Daten von 4 verschiedenen Sensoren mit serieller Kommunikation und möchte jede Sensordaten in einem separaten Diagramm plotten. Mein Code ist:Matplotlib - mehrere Diagramme von seriellen Daten

import serial 
import matplotlib.pyplot as plt 
import numpy as np 

connected = False 

comPort = 'COM4'   

ser = serial.Serial(comPort, 115200) # Sets up serial connection (make sure baud rate is correct - matches Arduino) 

while not connected: 
    serin = ser.read() 
    connected = True 

plt.ion()        # Sets plot to animation mode 

fig1 = plt.figure() 
fig2 = plt.figure() 
fig3 = plt.figure() 
fig4 = plt.figure() 

length = 20        # Determines length of data taking session (in data points); length/10 = seconds 

w = [0]*length       # Create empty variable of length of test 
x = [0]*length    
y = [0]*length 
z = [0]*length 

wline, = plt.plot(w)     # Sets up future lines to be modified 
xline, = plt.plot(x)      
yline, = plt.plot(y) 
zline, = plt.plot(z) 

plt.ylim(0,64535)      # Sets the y axis limits - 16 bits resolution 

for i in range(length):     # While you are taking data 
    data = ser.readline()    # Reads until it gets a carriage return (/n). 
    sep = data.split()     # Splits string into a list at the tabs 

    w.append(int(sep[0]))    # Add new values as int to current list 
    x.append(int(sep[1])) 
    y.append(int(sep[2])) 
    z.append(int(sep[3])) 

    del w[0] 
    del x[0] 
    del y[0] 
    del z[0] 

    wline.set_xdata(np.arange(len(w))) # Sets wdata to new list length 
    xline.set_xdata(np.arange(len(x))) 
    yline.set_xdata(np.arange(len(y))) 
    zline.set_xdata(np.arange(len(z))) 

    wline.set_ydata(w)     # Sets ydata to new lists 
    xline.set_ydata(x)     
    yline.set_ydata(y) 
    zline.set_ydata(z) 

    print i 
    print sep 

    ax1 = fig1.add_subplot(111) 
    ax1.plot(wline.set_ydata(w)) 
# ax1.plot(sep[0]) 
    plt.pause(0.001)     
    plt.grid(True) 
    plt.draw()       # Draws new plot 

    ax2 = fig2.add_subplot(111) 
    ax2.plot(xline.set_ydata(x)) 
    plt.pause(0.001)     
    plt.grid(True) 
    plt.draw()       # Draws new plot 

    ax3 = fig3.add_subplot(111) 
    ax3.plot(yline.set_ydata(y)) 
    plt.pause(0.001)     
    plt.grid(True) 
    plt.draw()       # Draws new plot 

    ax4 = fig4.add_subplot(111) 
    ax4.plot(zline.set_ydata(z)) 
    plt.pause(0.001)     
    plt.grid(True) 
    plt.draw()       # Draws new plot 

plt.show() 

ser.close()        # Closes serial connection 

Die erfassten Daten korrekt und die die vier Zahlen erzeugt werden, jedoch nur die letzte ist, die Daten Plotten. Außerdem werden alle 4 Sensoren geplottet und die Y-Achsen der anderen Subplots sind ebenfalls falsch (siehe Screenshot der Ausgabe). Ich drucke auch das Array, das die Daten enthält ("sep drucken"), nur um zu überprüfen, ob die Daten dort sind.

Screenshot of the program output

bin ich etwas fehlt offensichtlich? Vielen Dank für Ihre Hilfe

Antwort

1

Wenn Sie Ihre 4 Zeilen erstellen, werden sie alle für die aktive Figur erstellt (d. H. In diesem Fall die letzte, die Sie erstellt haben).

Sie könnten die Erstellung der 4 Teilplotachsen vor Ihre Schleife verschieben und dann die matplotlib-Linieninstanzen auf ihren korrekten Achsen erstellen (unter Verwendung der objektorientierten ax.plot anstelle von plt.plot). Dann werden sie auf die richtigen Zahlen zeigen.

fig1 = plt.figure() 
fig2 = plt.figure() 
fig3 = plt.figure() 
fig4 = plt.figure() 

ax1 = fig1.add_subplot(111) 
ax2 = fig2.add_subplot(111) 
ax3 = fig3.add_subplot(111) 
ax4 = fig4.add_subplot(111) 

length = 20        # Determines length of data taking session (in data points); length/10 = seconds 

w = [0]*length       # Create empty variable of length of test 
x = [0]*length    
y = [0]*length 
z = [0]*length 

wline, = ax1.plot(w)     # Sets up future lines to be modified 
xline, = ax2.plot(x)      
yline, = ax3.plot(y) 
zline, = ax4.plot(z) 

und dann können Sie die folgenden Zeilen von Code innerhalb der for-Schleife entfernen:

ax1 = fig1.add_subplot(111) 
ax1.plot(wline.set_ydata(w)) 
... 
ax2 = fig2.add_subplot(111) 
ax2.plot(xline.set_ydata(x)) 
... 
ax3 = fig3.add_subplot(111) 
ax3.plot(yline.set_ydata(y)) 
... 
ax4 = fig4.add_subplot(111) 
ax4.plot(zline.set_ydata(z)) 

Sie müssen auch

fig1.canvas.draw() 
fig2.canvas.draw() 
fig3.canvas.draw() 
fig4.canvas.draw() 

und die plt.grid(True) sollte jeder plt.draw() zu

ändern ändern zu:

ax1.grid(True) 
ax2.grid(True) 
ax3.grid(True) 
ax4.grid(True) 
+0

Vielen Dank, das hat das Problem effektiv gelöst. Ich habe auch die Skalierung ("Ylim") mit der gleichen Argumentation korrigiert (zum Beispiel mit 'ax1.set_ylim()' anstelle von 'plt'). Ein anderes Problem tauchte auf: Nur die aktive Figur aktualisiert "ihren" Plot in Echtzeit, dh durch Klicken/Auswählen einer bestimmten Figur wird diese Plot mit den kommenden Daten aktualisiert, aber die 3 anderen Figuren werden eingefroren, bis ich/wähle sie aus. Irgendeine Idee? Danke noch einmal. – Denis

+0

Ah, das liegt daran, dass 'plt.draw' nur auf die aktuelle Zahl wirkt. Sie sollten diese auf 'fig1.canvas.draw()' usw. umstellen. Siehe meine Bearbeitung oben. – tom

+0

Ich habe meinen vorherigen Kommentar bearbeitet. Danke @ Tom, es funktioniert. Alle Plots werden korrekt aktualisiert. – Denis

Verwandte Themen