Plotting Release on change data

Thanks John. This is an interesting application and sheds light in a
number of ways. Not quite what I'm looking for in terms of plot shape
but certainly addresses many of the issues with the asynchronous nature
of the incoming data. Thanks again for your fast response (and for
matplotlib in general).


-----Original Message-----
From: John Hunter [mailto:jdhunter@…4…]
Sent: Wednesday, August 31, 2005 3:08 PM
To: Smith, Frank
Subject: Re: [Matplotlib-users] Plotting Release on change data

    > Hello Matplotlib users, I only just discovered Matplotlib
    > and I'm having great fun with it. Wonderful package. Thank
    > you to all contributors and maintainers.

    > I have an application where the data that I want to plot is
    > only released when it changes. So when this time tagged
    > data is plotted it should be "flat" until the next data
    > value that the application receives at which point the line
    > should go instantaneously vertical to the new y-value, and
    > then go horizontal until it changes again. Some graphics
    > packages that I've used can handle this type of data
    > automatically. I haven't found anything in the
    > documentation or examples that shows this kind of feature
    > in Matplotlib. Has anyone implemented a similar type of
    > data handling application or is there something I've missed
    > in Matplotlib? Any help or direction to this newbie would
    > be very appreciated.

Here is an example that does something close to what you are trying to
do. It takes advantage of the new animation drawing techniques
described at
and requires matplotlib CVS. These techniques work with GTKAgg, WXAgg
and TkAgg.

To do this right, you will probably want to take advantage of your GUI
event handling framework, eg an idle handler or a timer. The example
below uses the gtk idle handler, but this approach should work fine with
other toolkits.

There are some refinements. Eg you could make the redrawing more
efficient potentially by narrowing the bbox you want to redraw in the
call to self.canvas.blit( You could also tweak this to
preserve the old line (eg the 0-10 second data) while you are redrawing
the new line (eg the 10-20 second data) in the way many oscilloscopes

But this should get you started. If you refine it or generalize it,
please post the fruits of your labors.

import gobject, gtk
import matplotlib
import matplotlib.numerix as nx
from matplotlib.lines import Line2D

class Scope:
    def __init__(self, ax, maxt=10, dt=0.01): = ax
        self.canvas = ax.figure.canvas
        self.dt = dt
        self.maxt = maxt
        self.tdata = [0]
        self.ydata = [0]
        self.line = Line2D(self.tdata, self.ydata, animated=True)
        self.background = None
        self.canvas.mpl_connect('draw_event', self.update_background), 1.1), self.maxt)

    def update_background(self, event):
        self.background = self.canvas.copy_from_bbox(
    def emitter(self, p=0.01):
        'return a random value with probability p, else 0'
        v = nx.mlab.rand(1)
        if v>p: return 0.
        else: return nx.mlab.rand(1)

    def update(self, *args):
        if self.background is None: return True
        y = self.emitter()
        lastt = self.tdata[-1]
        if lastt>self.tdata[0]+self.maxt: # reset the arrays
            self.tdata = [self.tdata[-1]]
            self.ydata = [self.ydata[-1]]
  [0], self.tdata[0]+self.maxt)
        t = self.tdata[-1] + self.dt
        self.line.set_data(self.tdata, self.ydata)
        return True

from pylab import figure, show

fig = figure()
ax = fig.add_subplot(111)
scope = Scope(ax)