Hi to the list,

I'm searching to display in realtime some data read serial port. The
data is a 2D matrix and is read element wise from the serial, one
pixel each one (or more) seconds.

I'm running the script from "ipython -pylab" using the command "run
scriptname". After "loading" the script I interactively launch the
function that start the data acquisition and I would like to see the
acquired data so far. In the loop that perform the data acquisition
I'm currently calling this function to plot data:

def plot_data_in_itinere(data, **kwargs):
   global first_plot
   d = data.ravel()[find(data.ravel() > 0)]
   m = d.mean()
   vr = round(5*d.std() / m, 3)
   #clf()
   title('Scanning Data')
   xlabel('Mean Value: '+str(int(round(m)))+' -- Relative Variation: '+str(vr))
   b,t = ylim()
   ylim(t,b)
   imshow(data.astype(float),
           interpolation='nearest',
           vmin=0,
           origin='lower', **kwargs)
   if first_plot:
       colorbar()
       first_plot = False

However the call to the function is "blocking". So the acquisition
time is longer (not only I have to wait the data but I have to wait
the plot too). Furthermore, this function plot the new data above the
old one, so the plot becomes slower and slower while the acquisition
goes on. If I uncommented the cla() line, I get a plot that is blank
most of the time and that shows the data only for a fraction of second
while the new plot is performed.

Is there a way to update (or substitute) the current showed matrix
data, deleting the old plots (in the axis). I have to confess that
I've have not understand well how the pylab interactive mode works.

Ideally the plot should be performed in background, while the script
goes on and wait the next data arrival. I've tried to do this with a
simple gtk app that embeds a matplotlib plot. Hoever, I don't know how
to send the application in background. I've tried to do something like
this:

class PlotScanApp:
...

class GuiThread(threading.Thread):
   def run(self):
       gtk.main()

if __name__ == '__main__':
   stdout = sys.stdout

   a = array(randn(100)).reshape(10,10)
   p = PlotScanApp(a)
   p.start()

   print 'Start image update:'

   for i in range(10):
       sleep(1)
       stdout.write('.')
       stdout.flush()
       p.plot(array(randn(100)).reshape(10,10))

the PlotScanApp implement the gui (full files attached). Running the
script the image should be updated with random data each 1 sec. but
only the first image is showed. I suppose this is not the way to put a
gui drawing app in background...

Any hints in how to do in the right way this gtk app that when
required update the plot?

Thank a lot.

Ciao,
 ~ Antonio
#!/usr/bin/env python
# -*- coding: UTF8 -*-

# Generic imports
import sys
import gtk
import gtk.glade
from pylab import *

# Import some matplotlib widgets or functions
from matplotlib.figure import Figure

# Import from matplotlib the FigureCanvas with GTKAgg backend
from matplotlib.backends.backend_gtkagg \
        import FigureCanvasGTKAgg as FigureCanvas

# Import the matplotlib Toolbar2
from matplotlib.backends.backend_gtk \
        import NavigationToolbar2GTK as NavigationToolbar

import threading
from time import sleep

# Global variables
homepath = '/home/anto/python/'
gladefile = homepath+'microlib.glade'

class PlotScanApp:
    """
    This class implements the Plot Scan Window.
    """
    def __init__(self, data, debug=False):
        
        # Data
        self.data = data
        self.debug = debug
        
        self.plot_kwargs = dict(
                linestyle = '-',
                linewidth = 1.5,
                marker = '.',
                alpha = 1
                )

        # Plot Defaults
        self.title = title
        self.xlabel = 'X Axis'
        self.ylabel = 'Y Axis'
        self.xscale = 'linear'
        self.yscale = 'linear'
        self.showPoints = True
        self.showLines = True
        self.grid = True

        # Load the GUI description
        self.windowname = 'PlotScanWindow'
        self.widgetTree = gtk.glade.XML(gladefile, self.windowname)
        self.window = self.widgetTree.get_widget(self.windowname)
       
        # Create the figure, the axis and the canvas
        self.figure = Figure()
        self.axis = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        
        # Add the canvas to the container
        self.container = self.widgetTree.get_widget('CanvasAlignment')
        self.container.add(self.canvas)
        
        # Create the matplotlib toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.window)
        toolbar_container = self.widgetTree.get_widget('ToolbarAlignment')
        toolbar_container.add(self.toolbar)
        
        self.widgetTree.signal_autoconnect(self)
        self.window.show_all()
        
        self.plot()

    def start(self):
        self.thread = GuiThread()
        self.thread.setDaemon(True)
        self.thread.start()

    def plot(self, data=None, **kwargs):
        if data != None: self.data = data
        #self.figure.clear()
        self.image = self.axis.imshow(self.data.astype(float), 
                interpolation='nearest', vmin=0, 
                origin='lower', **kwargs)
        bottom, top = self.axis.get_ylim()
        self.axis.set_ylim(top, bottom)
        #self.figure.colorbar(self.image)
        self.canvas.draw()

    def on_delete_event(self, widget, *args):
        return False
        
    def on_destroy(self, widget, data=None):
        gtk.main_quit()

class GuiThread(threading.Thread):
    def run(self):
        gtk.main()

if __name__ == '__main__':
    stdout = sys.stdout

    a = array(randn(100)).reshape(10,10)
    p = PlotScanApp(a)
    p.start()
    
    print 'Start image update:'
    
    for i in range(10):
        sleep(1)
        stdout.write('.')
        stdout.flush()
        p.plot(array(randn(100)).reshape(10,10))
        

Attachment: microlib.gladep
Description: Binary data

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to