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