Hi all!

I have a long running (non-GUI) python application, that needs to plot
some curves and update them in time, as new data are computed. I'm
well aware of ezplot, but would like to use a matplotlib-multiprocessing-only solution, as I have already enough
dependencies.

The best thing I have come so far with is essentially in the attached script (I stripped all unneeded dependencies and fancy stuff). It works quite well in terms that it plots as the data arrive, but I cannot find a way how to stop it cleanly. At the end, it just hangs (Ctrl-C does not help). I would appreciate any hints on what is wrong.

There are two classes: NBPlot spawns the new process and feeds it the data, ProcessPlotter is the "remote" plotter class plotting the data as they arrive. The plot update is done using gobject.timeout_add() according to the matplotlib examples. It can be run as:

$ python log.py

Best regards and thanks for your suggestions,
r.
import time
from multiprocessing import Process, Queue
from Queue import Empty
import numpy as np
import pylab
import gobject

class ProcessPlotter(object):

    def __init__(self):
        self.x = []
        self.y = []

    def terminate(self):
        pylab.close('all')

    def poll_draw(self):

        def call_back():
            while 1:
                try:
                    command = self.queue.get_nowait()
                except Empty:
                    break

                print command

                if command is None:
                    self.terminate()
                    return False

                else:
                    self.x.append(command[0])
                    self.y.append(command[1])
                    self.ax.plot(self.x, self.y, 'ro')

            self.fig.canvas.draw()
            return True

        return call_back
    
    def __call__(self, queue):
        print 'starting plotter...'

        self.queue = queue
        self.fig = pylab.figure()

        self.ax = self.fig.add_subplot(111)
        self.gid = gobject.timeout_add(1000, self.poll_draw())

        print '...done'
        pylab.show()


class NBPlot(object):
    def __init__(self):
        self.plot_queue = Queue()
        self.plotter = ProcessPlotter()
        self.plot_process = Process( target = self.plotter,
                                     args = (self.plot_queue,) )
        self.plot_process.daemon = True
        self.plot_process.start()
        
    def plot(self, finished=False):
        put =  self.plot_queue.put
        if finished:
            put(None)
        else:
            data = np.random.random(2)
            put(data)

def main():
    pl = NBPlot()
    for ii in xrange(10):
        pl.plot()
        time.sleep(0.5)
    raw_input()
    pl.plot(finished=True)

if __name__ == '__main__':
    main()
------------------------------------------------------------------------------
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to