-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic_plotter.py
executable file
·93 lines (73 loc) · 2.44 KB
/
dynamic_plotter.py
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
'''
A simple plotting library that plots lines in real time
Author: Jaden Travnik
Email: [email protected]
'''
import numpy as np
import matplotlib.pyplot as plt
import time
import matplotlib as mpl
#print(mpl.matplotlib_fname())
plt.switch_backend('TkAgg')
'''
Stores and updates the data for one matplotlib line.
If window_x is not None, the plotted data is restricted to that many data points
'''
class DynamicLine():
def __init__(self, window_x, line):
self.window_x = window_x
self.xdata = []
self.ydata = []
self.line = line
def add_point(self, _x, _y):
if self.window_x is not None and len(self.xdata) >= self.window_x:
self.xdata.pop(0)
self.ydata.pop(0)
self.xdata.append(_x)
self.ydata.append(_y)
#Update data (with the new _and_ the old points)
self.line.set_xdata(self.xdata)
self.line.set_ydata(self.ydata)
'''
A collection of DynamicLines, used to pass on data and redraw in its update function
'''
class DynamicPlot():
def __init__(self, title = None, xlabel = None, ylabel = None, window_x = None):
plt.ion()
self.figure, self.ax = plt.subplots()
self.lines = []
self.ax.set_autoscaley_on(True)
self.ax.grid()
self.window_x = window_x
if title:
self.ax.set_title(title)
if xlabel:
self.ax.set_xlabel(xlabel)
if ylabel:
self.ax.set_ylabel(ylabel)
def add_line(self, label = 'lineName'):
line, = self.ax.plot([],[], label = label)
self.lines.append(DynamicLine(self.window_x, line))
self.ax.legend(loc='upper center')
''' update
Accepts one y data point (eg. timestep) and an data array
which is ordered based on how the lines were added to the DynamicPlot
'''
def update(self, y, data):
for i in range(len(data)):
self.lines[i].add_point(y, data[i])
#Need both of these in order to rescale
self.ax.relim()
self.ax.autoscale_view()
#We need to draw *and* flush
self.figure.canvas.draw()
self.figure.canvas.flush_events()
# Example Usage
# d = DynamicPlot(window_x = 30, title = 'Trigonometry', xlabel = 'X', ylabel= 'Y')
# d.add_line('sin(x)')
# d.add_line('cos(x)')
# d.add_line('cos(.5*x)')
#
# for i in np.arange(0,40, .2):
# d.update(i, [np.sin(i), np.cos(i), np.cos(i/.5)])
# time.sleep(.01)