On Mar 27, 2007, at 12:35 PM, Antonino Ingargiola wrote:
>
> 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.

You shouldn't have any problems making this happen, although it  
requires a lot more legwork than creating normal interactive plots.

> 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.

I've never tried to do something like this using pylab before, so I  
probably can't be of much help there.  However, I can point you  
toward an example of how to do it from within wxPython using a timer.

> 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).

You should probably do the acquisition asynchronously by running it  
in a separate thread.  That thread would read in the data one point  
at a time, perform any pre-processing, and post the results to a  
place that's shared between it and the main plotting thread.  The  
main thread would periodically check and see if the shared data has  
changed and redraw the plot if needed.  I'm not sure how hard this is  
to do in a reasonable way in pylab, but I've used this approach  
before in wxPython GUIs.

> 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.
`
You might want to consider create a mock data source that generates a  
stream of values from some pre-collected data or Python's "random"  
module.  That would let you work on debugging the plotting end of  
things first.  It would also make it easier for you to share your  
code with the list.

> 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.

pylab.imshow() returns a matplotlib.image.AxesImage object.  It looks  
like you can update the data array using its set_data() method.  The  
class documentation is available on the matplotlib website:

        http://matplotlib.sourceforge.net/matplotlib.image.html#AxesImage

> Ideally the plot should be performed in background, while the script
> goes on and wait the next data arrival.

You'd almost certainly be happier doing things the other way around.   
Most GUI toolkits are extremely fussy about what thread the GUI event  
loop runs in.  For example, wxPython requires App.MainLoop() be  
called from the thread that first imported the wxPython module.  That  
being said, it's possible to run the GUI thread in the background --  
the iPython wizards might be able to help you figure it out.

> 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:
>
<snip>
>
> 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...

Well, using pylab from within a GUI application is a bit dodgy to  
begin with.  I can see a few potential problems.  The first is that  
you're calling plotting commands from within the main thread,  
although the GUI is running in a background thread.  You might try  
doing the plotting from within the GUI thread by having a timer fire  
once a second to redraw the plot.  The second problem is that you're  
not calling pylab.draw(), which forces the current figure to redraw  
itself.  Whether or not pylab is running in interactive mode might be  
a factor here.  There's some documentation about interactive mode and  
the ion()/ioff() commands here:

        http://matplotlib.sourceforge.net/interactive.html

Ken

-------------------------------------------------------------------------
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