出于某种原因,我没有在下面的代码中绘制任何线条。目标是将我通过序列返回的温度绘制成图形,将时间绘制在X上,将温度绘制在Y上。
$ python -c 'import matplotlib; import matplotlib.pyplot; print(matplotlib.backends.backend)'
TkAgg
$ python3 -c 'import matplotlib; import matplotlib.pyplot; print(matplotlib.backends.backend)'
Qt5Agg
串行数据:
['20.00', '24.00', '22.00', '22.19', '22.25']
['20.00', '24.00', '21.90', '22.19', '22.25']
['20.00', '24.00', '21.90', '22.12', '22.25']
['20.00', '24.00', '21.90', '22.12', '22.25']
['20.00', '24.10', '21.90', '22.19', '22.25']
['20.00', '24.10', '21.90', '22.19', '22.25']
['20.00', '24.10', '21.90', '22.19', '22.25']
['20.00', '24.20', '21.90', '22.19', '22.31']
代码:
import sys, serial, argparse
import datetime
import numpy as np
from time import sleep
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.dates import DateFormatter
class SerialReader:
def __init__(self, port, baudrate, ys=4):
self.ser = serial.Serial(port, baudrate)
self.ax = []
self.ays = {}
for i in range(0, ys):
self.ays[i] = []
def read(self):
line = self.ser.readline()
data = line.decode("utf8").rstrip().split("\t")
if not len(data)==len(self.ays):
return False
return data
def update(self, frameNum, *args):
try:
from pprint import pprint
values = self.read()
# happens only ones due to boot
if not values:
values = self.read()
pprint(values)
data = [float(val) for val in values]
self.ax.append(datetime.datetime.now())
for i in self.ays:
self.ays[i].append(data[i])
i=0
for a in args:
a.set_data(self.ax, self.ays[i])
i+=1
except KeyboardInterrupt:
print('exiting')
return args
def close(self):
self.ser.flush()
self.ser.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Temp reader")
parser.add_argument('-p', '--port', dest='port', default="/dev/ttyUSB0")
parser.add_argument('-b', '--baud', dest='baud', default=9600, type=int)
args = parser.parse_args()
port = args.port
baudrate = args.baud
amount = 5
reader = SerialReader(port, baudrate, amount)
fig, ax = plt.subplots()
ax.autoscale_view()
ax.fmt_xdata = DateFormatter('%H:%M:%S')
plt.xlabel("Time")
plt.ylabel("Temperature")
lines = []
lines.append(ax.plot_date([], [], '-', label = 'DHT11')[0])
lines.append(ax.plot_date([], [], '-', label = 'DHT22 #1')[0])
lines.append(ax.plot_date([], [], '-', label = 'DHT22 #1')[0])
lines.append(ax.plot_date([], [], '-', label = 'MCP9808 #1')[0])
lines.append(ax.plot_date([], [], '-', label = 'MCP9808 #2')[0])
ax.legend(lines, [l.get_label() for l in lines], loc=0)
fig.autofmt_xdate()
anim = animation.FuncAnimation(fig, reader.update, fargs=lines, blit=True, interval=4000)
fig.autofmt_xdate()
plt.show()
reader.close()
答案 0 :(得分:0)
下面的确有效,但远非漂亮... t.b.h.我现在不在乎,只是很高兴它的工作原理,让它留在那里。
import datetime
import argparse
import serial
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
class SerialReader(object):
def __init__(self, port, baudrate):
self.ser = serial.Serial(port, baudrate)
def __iter__(self):
return self
def __next__(self):
return self.next()
def next(self):
line = self.ser.readline()
return [float(val) for val in line.decode("utf8").split("\t")]
def loop(self):
try:
while True:
yield self.next()
except KeyboardInterrupt:
self.close()
raise StopIteration()
def close(self):
self.ser.flush()
self.ser.close()
if __name__ == '__main__':
# create parser
parser = argparse.ArgumentParser(description="Temp reader")
# add expected arguments
parser.add_argument('-p', '--port', dest='port', default="/dev/ttyUSB0")
parser.add_argument('-b', '--baud', dest='baud', default=9600, type=int)
# parse args
args = parser.parse_args()
port = args.port
baudrate = args.baud
fig, ax = plt.subplots(1, 1)
ax.set_ylim(15, 25)
ax.hold(True)
rw = SerialReader(port, baudrate)
# to avoid incomplete line
rw.next()
y1, y2, y3, y4, y5 = rw.next()
x = datetime.datetime.now()
xfmt = DateFormatter('%H:%M:%S')
ax.fmt_xdata = xfmt
ax.xaxis.set_major_formatter(xfmt)
ax.autoscale_view()
plt.ion()
plt.show(False)
plt.draw()
lines = [
ax.plot_date(x, y1, '-', label='DHT11')[0],
ax.plot_date(x, y2, '-', label='DHT22 #1')[0],
ax.plot_date(x, y3, '-', label='DHT22 #2')[0],
ax.plot_date(x, y4, '-', label='MCP9808 #1')[0],
ax.plot_date(x, y5, '-', label='MCP9808 #2')[0]
]
ax.legend(lines, [l.get_label() for l in lines], loc=0)
xs = []
ys1 = []
ys2 = []
ys3 = []
ys4 = []
ys5 = []
for y1, y2, y3, y4, y5 in rw.loop():
now = datetime.datetime.now()
xs.append(now)
ax.set_xlim([x, now])
ys1.append(y1)
ys2.append(y2)
ys3.append(y3)
ys4.append(y4)
ys5.append(y5)
ax.set_ylim([min(ys1+ys2+ys3+ys4+ys5)-1, max(ys1+ys2+ys3+ys4+ys5)+1])
lines[0].set_data(xs, ys1)
lines[1].set_data(xs, ys2)
lines[2].set_data(xs, ys3)
lines[3].set_data(xs, ys4)
lines[4].set_data(xs, ys5)
fig.autofmt_xdate()
fig.canvas.draw()
plt.show(False)
# ttyUSB is slow
plt.pause(4)
plt.close(fig)