2024-09-16 10:08:19 -04:00
|
|
|
import matplotlib.pyplot as plt
|
2024-09-12 15:07:58 -04:00
|
|
|
|
|
|
|
class DynamicSeries:
|
2024-09-16 10:08:19 -04:00
|
|
|
def __init__(self, fig, ax, x_lim = [0,10], y_lim = [0,10]):
|
2024-09-12 15:07:58 -04:00
|
|
|
self.fig = fig
|
|
|
|
self.ax = ax
|
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
self.fig.show()
|
|
|
|
# Create the one line that will be drawn onto the plot.
|
|
|
|
# ``plot`` returns a list of the things plotted, so get
|
|
|
|
# the only element of the list, the line.
|
|
|
|
self.ln = ax.plot([0,1], [0,1], 'r-', animated=True)[0]
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
self.x_lim = x_lim
|
|
|
|
self.y_lim = y_lim
|
|
|
|
self.ax.set_xlim(*self.x_lim)
|
|
|
|
self.ax.set_ylim(*self.y_lim)
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
# Redraw the figure when matplotlib requests a redraw.
|
|
|
|
self.fig.canvas.mpl_connect("draw_event", self.on_draw)
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
# Initialize data fed into the series
|
2024-09-12 15:07:58 -04:00
|
|
|
self.x_ax = []
|
|
|
|
self.y_ax = []
|
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
def set_color(self, *args, **kwargs):
|
|
|
|
self.ln.set_color(*args, **kwargs)
|
|
|
|
|
|
|
|
def draw_event(self, *args):
|
|
|
|
self.on_invalidated()
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
def on_invalidate(self):
|
|
|
|
""" This function redraws all data to the screen whenever the
|
|
|
|
screen is "invalidated". This could mean a user resize,
|
|
|
|
or an automatic axis resize. """
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
self.ax.clear()
|
|
|
|
self.ax.set_xlim(*self.x_lim)
|
|
|
|
self.ax.set_ylim(*self.y_lim)
|
|
|
|
#self.fig.canvas.draw()
|
2024-09-12 15:07:58 -04:00
|
|
|
|
2024-09-16 10:08:19 -04:00
|
|
|
self.ln.set_xdata(self.x_ax)
|
|
|
|
self.ln.set_ydata(self.y_ax)
|
|
|
|
self.ax.draw_artist(self.ln)
|
|
|
|
self.fig.canvas.blit(self.fig.bbox)
|
|
|
|
def on_draw(self, *args, **kwargs):
|
|
|
|
self.on_invalidate()
|
|
|
|
|
|
|
|
def add(self, x, y):
|
|
|
|
""" Add two points to the graph and redraw it.
|
|
|
|
Returns True if the graph was redrawn. """
|
|
|
|
haveToRedraw = False
|
|
|
|
|
|
|
|
# If there were no previous points, do nothing. There is not
|
|
|
|
# enough data to draw a line.
|
|
|
|
if len(self.x_ax) == 0:
|
|
|
|
self.x_ax = [x]
|
|
|
|
self.y_ax = [y]
|
|
|
|
return False
|
|
|
|
|
|
|
|
# If there was a previous point, use it to draw a line to the
|
|
|
|
# current point. Store the current point as data.
|
2024-09-12 15:07:58 -04:00
|
|
|
prev_x = self.x_ax[-1]
|
|
|
|
prev_y = self.y_ax[-1]
|
2024-09-16 10:08:19 -04:00
|
|
|
self.x_ax.append(x)
|
|
|
|
self.y_ax.append(y)
|
|
|
|
|
|
|
|
# If the point is outside of the limits of the graph, change the
|
|
|
|
# limits and redraw the graph.
|
|
|
|
if x < self.x_lim[0]:
|
|
|
|
self.x_lim[0] = x - 0.01*x
|
|
|
|
haveToRedraw = True
|
|
|
|
elif x > self.x_lim[1]:
|
|
|
|
self.x_lim[1] = x + 0.01*x
|
|
|
|
haveToRedraw = True
|
|
|
|
|
|
|
|
if y < self.y_lim[0]:
|
|
|
|
self.y_lim[0] = y - 0.01*y
|
|
|
|
haveToRedraw = True
|
|
|
|
elif y > self.y_lim[1]:
|
|
|
|
self.y_lim[1] = y + 0.01*y
|
|
|
|
haveToRedraw = True
|
|
|
|
|
|
|
|
if haveToRedraw:
|
|
|
|
self.fig.canvas.draw()
|
|
|
|
return True
|
|
|
|
|
|
|
|
print((prev_x, x), (prev_y, y))
|
|
|
|
self.ln.set_xdata([prev_x, x])
|
|
|
|
self.ln.set_ydata([prev_y, y])
|
|
|
|
self.ax.draw_artist(self.ln)
|
2024-09-12 15:07:58 -04:00
|
|
|
self.fig.canvas.blit(self.fig.bbox)
|
|
|
|
self.fig.canvas.flush_events()
|
2024-09-16 10:08:19 -04:00
|
|
|
return False
|