标题是我正在使用一个沿串行端口输出数据的Arduino。它输出如下:
120 1.23 170 2.54 210 2.32
左列是以毫秒为单位的时间,右列是0到5V之间的电压值。由空格隔开。编辑:看来stackoverflow不会让我以表格形式打印,所以要说清楚,我有120空间1.23 \换行170空格2.54等等。 我正在使用的Arduino草图:
#include <eHealth.h>
unsigned long time;
// The setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
}
// The loop routine runs over and over again forever:
void loop() {
float ECG = eHealth.getECG();
time = millis();
Serial.print(time);
Serial.print(" ");
Serial.print(ECG, 3);
Serial.println("");
delay(50); // wait for 50 millisecond
}
现在在python的最后,我尝试了一些不同的脚本来使它工作,但到目前为止还没有成功。我想沿x轴(数据的左列)打印时间(以毫秒为单位)与电压值(右列)打印,并沿x轴更新时间,以便随输入数据一起变化。
我遇到的其中一段代码是这一段,但这似乎更适合在同一图表上绘制两段数据,这不是我想要的:
import sys, serial
import numpy as np
from time import sleep
from collections import deque
from matplotlib import pyplot as plt
import time
# class that holds analog data for N samples
class AnalogData:
# constr
def __init__(self, maxLen):
self.ax = deque([0.0]*maxLen) # maxLen = no. of samples?
self.ay = deque([0.0]*maxLen)
self.maxLen = maxLen
# ring buffer
def addToBuf(self, buf, val):
if len(buf) < self.maxLen:
buf.append(val)
else:
buf.pop()
buf.appendleft(val)
# add data
def add(self, data):
assert(len(data) == 2)
self.addToBuf(self.ax, data[0])
self.addToBuf(self.ay, data[1])
# plot class
class AnalogPlot:
# constr
def __init__(self, analogData):
# set plot to animated
plt.ion()
self.axline, = plt.plot(analogData.ax)
self.ayline, = plt.plot(analogData.ay)
plt.ylim([0,10])
# update plot
def update(self, analogData):
self.axline.set_ydata(analogData.ax)
self.ayline.set_ydata(analogData.ay)
plt.draw()
def main(): # main() function
analogData = AnalogData(200) # data range (maxLen)
analogPlot = AnalogPlot(analogData)
print 'plotting data...'
# open serial port
ser = serial.Serial('/dev/tty.usbmodem1411', 9600)
blt = 0
blot = []
for i in range(5) : # total data points to plot
line = ser.readline()
data = [float(val) for val in line.split(" ")]
blt = blt+1
blot.append(float(val))
#print blot
print data
if(len(data) == 2):
analogData.add(data)
analogPlot.update(analogData)
#close serial
ser.flush()
ser.close()
time.sleep(1)
plt.close("all")
f=open("plot_store_1", "w")
f.write("\n".join(str(x) for x in blot))
plt.close("all")
# call main
if __name__ == '__main__':
main()
理想情况下,我想要一个像这样的输出:
答案 0 :(得分:0)
这里有一个例子,说明你如何做你想做的事,但首先要做一些注意事项:
N
,您可以控制最多要绘制的点数refreshMillis
控制绘图的刷新率现在代码:
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
import matplotlib.figure as mfig
import PyQt4.QtGui as gui, PyQt4.QtCore as core
import collections
import time
import random
#import serial
#ser = serial.Serial('/dev/tty.usbmodem1411', 9600)
#def get_line():
# return ser.readline()
def get_line():
x = time.time()%10000
y = random.random() * 5
return "%d %.3f\n" % (x,y)
refreshMillis = 300
N = 10
xs = collections.deque(maxlen=N)
ys = collections.deque(maxlen=N)
app = gui.QApplication([])
fig = mfig.Figure()
canvas = FigureCanvasQTAgg(fig)
ax = fig.add_subplot(111)
ax.set_ylim([0,5])
line2D, = ax.plot(xs,ys)
canvas.show()
def process_line():
line = get_line()
data = map(float,line.split(' '))
xs.append(data[0])
ys.append(data[1])
line2D.set_data(xs,ys)
xmin, xmax = min(xs),max(xs)
if xmin == xmax:
ax.set_xlim([xmin,xmin+1])
else:
ax.set_xlim([xmin,xmax])
canvas.draw()
timer = core.QTimer()
timer.timeout.connect(process_line)
timer.start(refreshMillis)
app.exec_()
#ser.flush()
#ser.close()