-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpy_serialPlotCustom
169 lines (127 loc) · 4.22 KB
/
py_serialPlotCustom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#Forked from https://github.com/patou01/py_serialPlot
#Thanks to Patou01!
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import serial
import time
import platform
from cycler import cycler
from io import BytesIO
#### SETTINGS
# serial port
serialPort = 'COM4'
baud = 921600
# number of points to view
windowSize = 300
# number of data to plot (not including x)
nData = 5;
# if separatePlots is True, each set is plotted on a different subplot
# all subplots have same X however.
separatePlots = False
# allow custom labels for data
useCustomLabels = True
# if using custom labels, you are responsible for having as many entries as nData
customLabels = ['Avg', 'Fast', 'Slow', 'Min', 'Max']
# if true, use first input from serial as x axis, else just plot it
firstInputAsX = True
# Only used to estimate the x interval to display at the beginning
# dt is ~ the time expected between 2 points.
# Only used when firstInputAsX is True
dt = 1
# y auto resize. If autoResizeY set to False, please give minY < maxY
autoResizeY = False
minY = -2
maxY = 2
###### END SETTINGS
print("Using python: " + platform.python_version())
print("Using numpi: " + np.__version__)
print("Using matplotlib: " + matplotlib.__version__)
print("Serial: " + serial.__version__)
ser = serial.Serial(serialPort, baud)
x = np.array([0.0])
y = np.zeros(shape=(1,nData))
lines = []
ax = []
intX = int(firstInputAsX)
if firstInputAsX:
dataNames = 'x'
else:
dataNames = 'y0'
dNames = [dataNames]
for i in range(int(not firstInputAsX), nData):
dataNames = dataNames + ', y' + str(i)
dNames = np.append(dNames, 'y' + str(i))
# dataTypes for parsing serial line
dataTypes = []
for i in range(0, intX+nData): # 1+ because of x input
dataTypes = np.append(dataTypes, np.dtype(np.float))
# making and styling figure
plt.style.use('seaborn-darkgrid')
plt.rc('figure', facecolor='darkgrey')
plt.rc('figure.subplot', left=0.05, right=0.98, top=0.98, bottom=0.1)
plt.rc('xtick', labelsize=7)
plt.rc('ytick', labelsize=7)
plt.rc('lines', linewidth=1)
plt.rc('legend', frameon=True, loc='upper left', facecolor='white', framealpha=0.5, fontsize=7)
plt.rc('axes', prop_cycle=(cycler(color=['b','g','r','c','y','m','k']) +
cycler(linestyle=['-.','-','-',':',':','-','-'])))
plt.rc('font', size=7)
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(1,1,1, navigate=True)
ax.set_autoscale_on(True)
ax.autoscale_view(True,True,True)
# add lines to plot
for i in range(0, nData):
lines = np.append(lines, ax.plot(x, y[:,i]))
# add labels
if useCustomLabels:
ax.legend(customLabels)
else:
ax.legend(dNames[intX:len(dNames)])
lastDisplay = time.time()
while True:
start = time.time()
# read line on serial
while ser.inWaiting():
line = ser.readline()
f = BytesIO(line)
data = np.genfromtxt(f, names = dataNames, dtype = dataTypes)
# handle nans
for i in range(0, nData + intX):
if np.isnan(data[dNames[i]]):
data[dNames[i]] = 0
# add data to Y arrays
yTemp = []
for i in range(intX, nData+intX):
yTemp = np.append(yTemp, data[dNames[i]])
y = np.vstack([y, yTemp])
# add data to X array
if firstInputAsX:
x = np.append(x, data['x'])
else:
x = np.append(x, x[x.size-1] + 1)
# update data
for i in range(0, nData):
if x.size > windowSize:
lines[i].set_ydata(y[y[:,i].size-windowSize:y[:,i].size,i])
lines[i].set_xdata(x[x.size-windowSize:x.size])
else:
lines[i].set_ydata(y[:,i])
lines[i].set_xdata(x)
end = time.time()
lastDisplay = time.time()
ax.autoscale_view(True,x.size < windowSize,autoResizeY)
if not autoResizeY:
ax.set_ylim(minY, maxY)
if x.size < windowSize :
if firstInputAsX:
ax.set_xlim(0, dt*windowSize)
else:
ax.set_xlim(0, windowSize)
else:
ax.set_xlim(x[x.size-windowSize], x[x.size-1], True, True)
ax.relim()
fig.canvas.draw()
fig.canvas.flush_events()