Ich stream Beschleunigungsmesser Daten von meinem Android-Handy und haben erfolgreich ein Live-Plot mit Matplotlib gebaut. Ich verwende den Komma-Operator, um den Plot dynamisch zu aktualisieren, aber ich frage mich, ob es eine elegantere/pythischere Art gibt, es zu tun. Um den folgenden Code auszuführen, müssen Sie die App Sensorstream IMU+GPS verwenden. Der folgende Code erfasst die Beschleunigungsmesserwerte und zeichnet sie live auf. Ich basierte das Plotten auf Can you plot live data in matplotlib?. Wie ich schon sagte, es funktioniert, aber der Code ist ungeschickt. Auch bei den in der matplotlib documentation genannten Beschleunigungen liege ich bei ca. 25 FPS. Die Technik, wenn ich nur eine einfache Grafik verwende, kann bis zu 90 FPS erreichen. Es kann gezeigt werden, dass Sie ~ 200 FPS schneller hier erreichen können why is plotting with Matplotlib so slow?. Ich kann meinen Engpass nicht finden. Gibt es also eine elegantere Methode, um alle Subplots zu kodieren? Zweitens, kann ich das Plotten beschleunigen?Plotten von Streaming-Daten in Matplotlib: Die Notwendigkeit für die Geschwindigkeit
import socket, traceback
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter,iirfilter,savgol_filter
import math
import pylab
from pylab import *
import time
import numpy as np
host = ''
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((host, port))
# lists for plotting
Ax = [0.0] * 50
Ay = [0.0] * 50
Az = [0.0] * 50
G = [0.0] * 50
x = [i for i in range(len(Ax))]
#used for debugging
fig = plt.figure(figsize=(16,10))
# raw data
ax = plt.subplot("311")
ax.set_xlim(0, 50)
ax.set_ylim(-2, 2)
ax.set_title("Raw acceleration data")
ax.set_ylabel("g$/m^2$",fontsize=18)
ax.hold(True)
line = ax.plot(Ax,label='Acc x')[0]
line2 = ax.plot(Ay,label='Acc y')[0]
line3 = ax.plot(Az,label='Acc z')[0]
# filtered data
ax2 = plt.subplot("312")
ax2.set_xlim(0, 50)
ax2.set_ylim(-2, 2)
ax2.set_title(" acceleration data")
ax2.set_ylabel("g$/m^2$",fontsize=18)
ax2.hold(True)
f_line = ax2.plot(Ax,label='Acc x')[0]
f_line2 = ax2.plot(Ay,label='Acc y')[0]
f_line3 = ax2.plot(Az,label='Acc z')[0]
# tilt angle plot
ax3 = plt.subplot("313")
ax3.set_ylim([-180,180])
ax3.set_title("Tilt Angles")
ax3.set_ylabel("degrees",fontsize=18)
t_line = ax3.plot(G)[0]
fig.suptitle('Three-axis accelerometer streamed from Sensorstream',fontsize=18)
plt.show(False)
plt.draw()
# cache the background
background = fig.canvas.copy_from_bbox(fig.bbox)
count = 0
print("Success binding")
while 1:
# time it
tstart = time.time()
message, address = s.recvfrom(8192)
messageString = message.decode("utf-8")
Acc = messageString.split(',')[2:5]
Acc = [float(Acc[i])/10.0 for i in range(3)]
# appending and deleting is order 10e-5 sec
Ax.append(Acc[0])
del Ax[0]
Ay.append(Acc[1])
del Ay[0]
Az.append(Acc[2])
del Az[0]
G.append(np.sqrt(Ax[-1]**2 + Ay[-1]**2 + Az[-1]**2))
del G[0]
# filter
acc_x_savgol = savgol_filter(Ax, window_length=5, polyorder=3)
acc_y_savgol = savgol_filter(Ay, window_length=5, polyorder=3)
acc_z_savgol = savgol_filter(Az, window_length=5, polyorder=3)
tilt_angles = []
for i,val in enumerate(G):
angle = math.atan2(Ax[i], -1*Ay[i]) * (180/math.pi)
if (math.isnan(angle)):
tilt_angles.append(0)
else:
tilt_angles.append(angle)
print(Ax[0],Ay[1],Az[2])
line.set_xdata(x)
line.set_ydata(Ax)
line2.set_xdata(x)
line2.set_ydata(Ay)
line3.set_xdata(x)
line3.set_ydata(Az)
ax.set_xlim(count, count+50)
f_line.set_xdata(x)
f_line.set_ydata(acc_x_savgol)
f_line2.set_xdata(x)
f_line2.set_ydata(acc_y_savgol)
f_line3.set_xdata(x)
f_line3.set_ydata(acc_z_savgol)
ax2.set_xlim(count, count+50)
t_line.set_xdata(x)
t_line.set_ydata(tilt_angles)
ax3.set_xlim(count, count+50)
# restore background
fig.canvas.restore_region(background)
# redraw just the points
ax.draw_artist(line)
ax.draw_artist(line2)
ax.draw_artist(line3)
ax2.draw_artist(f_line)
ax2.draw_artist(f_line2)
ax2.draw_artist(f_line3)
ax3.draw_artist(t_line)
# fill in the axes rectangle
fig.canvas.blit(fig.bbox)
count+=1
x = np.arange(count,count+50,1)
# tops out at about 25 fps :|
print "Total time for 1 plot is: ",(time.time() - tstart)
Vielleicht vermisse ich etwas, aber könnten Sie ein wenig genauer sein, wie dies die Fragen beantwortet? – superhero
Ich wollte sagen, Sie müssen die Ergebnisse vor dem Zeichnen() 'plotten()'. Auf diese Weise weiß der Interpreter, dass die Leinwand mit Unterparzellen gefüllt ist. –