from datetime import datetime, timedelta import matplotlib import matplotlib.pyplot as plt import matplotlib.dates as mdates class Chart: def __init__(self, samples = 50, title = None, limits = None, batch=False, show=True, fullscreen=False, read_x=False): self.start = datetime.now() self.x = [] self.y = [] self.samples = samples self.fig = plt.figure() self.axis = self.fig.add_subplot(111, autoscale_on = True, xticklabels = []) scale_axis = "both" if not limits else "x" self.axis.autoscale(enable=True, axis=scale_axis, tight = 2) # save limits self.limits = limits self.title = title self.axis.set_label(title) self.fig.canvas.draw() self.draw_opts = 'r-' self.line = False # upate timeout code (limit to 10fps) self.last_update = datetime.min self.update_timeout = timedelta(seconds=0.1) self.read_x = read_x # if batch mode, do not use timestamp when read from stdin self.batch = batch self.fullscreen = fullscreen if show: plt.show(block=False) def ui_update(self, final_draw=False): if len(self.y) < 2: return if not final_draw and datetime.now() - self.last_update < self.update_timeout: return self.axis.clear() # call plot method that is easily overrideable self.plot() if self.limits: self.axis.set_ylim(self.limits) if not self.batch: self.axis.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S")) self.fig.autofmt_xdate() if self.fullscreen: plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0) else: plt.title(self.title) self.fig.canvas.draw() self.fig.canvas.flush_events() self.last_update = datetime.now() def plot(self): if self.batch: self.axis.plot(self.y, self.draw_opts) else: self.axis.plot_date(self.x, self.y, self.draw_opts) def read_input(self, input): self.y.append(float(input)) self.x.append(datetime.now()) if self.samples > 0 and len(self.y) > self.samples: self.y.pop(0) self.x.pop(0) self.ui_update() def save_to_file(self, file): self.ui_update(final_draw = True) plt.savefig(file)