incrementalgraph/dynamicseries.py

99 lines
3.1 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import matplotlib.pyplot as plt
class DynamicSeries:
def __init__(self, fig, ax, x_lim = [0,10], y_lim = [0,10]):
self.fig = fig
self.ax = ax
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]
self.x_lim = x_lim
self.y_lim = y_lim
self.ax.set_xlim(*self.x_lim)
self.ax.set_ylim(*self.y_lim)
# Redraw the figure when matplotlib requests a redraw.
self.fig.canvas.mpl_connect("draw_event", self.on_draw)
# Initialize data fed into the series
self.x_ax = []
self.y_ax = []
def set_color(self, *args, **kwargs):
self.ln.set_color(*args, **kwargs)
def draw_event(self, *args):
self.on_invalidated()
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. """
self.ax.clear()
self.ax.set_xlim(*self.x_lim)
self.ax.set_ylim(*self.y_lim)
#self.fig.canvas.draw()
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.
prev_x = self.x_ax[-1]
prev_y = self.y_ax[-1]
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)
self.fig.canvas.blit(self.fig.bbox)
self.fig.canvas.flush_events()
return False