Thanks for the code! I'll study it, and the alternatives you recommended, then get back to the list with the result.

For now, I'm using PythonCard's scrolledMessageDialog to display a quick&dirty vertically-oriented text bar graph:

   def drawSpectrum(self, channel=None):
       if channel is None or channel < 1:
           return False
       chan = channel - 1   # Convert 1-n channel ID to list index
       count = len(theChannels[chan].aTheSpectrum.aSpectrum)
       if count is None or count < 1:
           return False
       # A really dumb max() function.  There's got to be a better way...
       max = theChannels[chan].aTheSpectrum.aSpectrum[0]
       for i in range(1,count):
           if max < theChannels[chan].aTheSpectrum.aSpectrum[i]:
               max = theChannels[chan].aTheSpectrum.aSpectrum[i]
       # Make a big string containing the bar graph.
# Assume we can fit 100 "|" on a line, without wrapping. Adjust as needed.
       scale = 100.0/max   # Create a multiplicative scale factor
str = "Max counts = %d. Each '|' = %0.2f counts. Longest line is 100 '|' long.\n"%(max,(1/scale))
       for i in range(0,count):
str += "% 4d "%i + "|"*int(theChannels[chan].aTheSpectrum.aSpectrum[i]*scale) + "\n"
       dialog.scrolledMessageDialog(self, str, 'Spectrum %d'%channel)

If anyone wants to beat on this to make it more "Pythonic", I'm here to learn...

-BobC


Christopher Barker wrote:
Robert Cunningham wrote:
I'd like to plot the set using a simple "value" vs "channel #" bar graph.

I've looked at the existing demos, and either I'm too much of a newbie to comprehend them, or they don't quite provide the template I need. Is there some demo code available to help me create this simple plot?

Are you looking at just the stuff that comes with PythonCard or wxPython? If so, be sure to check out the stuff in SVN:

http://svn.wxwidgets.org/viewvc/wx/wxPython/3rdParty/FloatCanvas/Demos/

MovingPlot.py and ScaleDemo.py may be helpful.

(Minor rant: Detailed FloatCanvas docs could keep me off the list... Examples & demos tell me "what", but not "why".)

Well, yes, but someone's got to write them! Contributions accepted.

Or is FloatCanvas not the best tool for the job?

It's do the job, but as you've noticed does not have any built-in support for axes, etc.


(My backup plan is to use GnuPlot to generate an image then shove it into a canvas, but I'd lose interactivity.)

I wouldn't do that. However, you might want to look at matplotlib, (and wxmpl for helping put it into a wx app) performance will be worse that FloatCanvas, but there is a lot of nifty plotting stuff supported.

There are also a couple other plotting widgets for wxPython -- one in the wxPython distribution that is very limited, and couple others that have been talked about on the mailing list.

Anyway, I did a bit, and worked up a demo that I think is a start of what you want. It's enclosed, and now in FloatCanvas SVN (which is now part of wxPython SVN) It's tested against SVN head, so it may not work with an older FloatCanvas (though it may).

Note that I'm creating a rectangle object for each bar on the plot. That requires that you loop through them all to re-set the values. For better performance, it would be better to create a custom BarPlot DrawObject that kept one data set, and it would draw the individual rectangles.

There is an issue -- If I put in 1024 data points, then each bar ends up less than a pixel wide, which gets rounded down to zero, and nothing gets drawn. It gets drawn fine when you zoom in, though. I thought we could just add a "minimum width" parameter to FloatCanvas.Rectangle, but it's not that simple, the truncation happens when WorldToPixel creates an integer.

So, in this version, I wrote a new ScaleWorldToPixel method that rounds up, and injected into FloatCanvas before using it -- Python is so cool!

I don't want to change it globally, as others might not want that behavior.

Another issue is zooming -- if you zoom in, you might want to zoom in to the X axis, but re-scale the y axis so you can still see the entire height of the bars. You could do that by writing a GUIMode that captures the zoom and re-defines the projection function. Or you could do the scaling in your BarPlot object, if you wrote one -- that might be the better way to go.

In short, FloatCanvas has the infrastructure you need, but it's going to take some work to get everything you probably want -- you're probably better off with Matplotlib.


-Chris


------------------------------------------------------------------------

_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

--
Robert Cunnigham
Chief Engineer, SDTI
[EMAIL PROTECTED]
Ph: 858-332-0700  ext. 118
Fax:858-332-0709

SD Technologies, Inc.
C/O Space Micro, Inc.
http://www.spacemicro.com/
10401 Roselle Street Suite 400
San Diego, CA 92121
begin:vcard
fn:Robert Cunningham
n:Cunningham;Robert
org:Space Micro;DSD
adr;dom:;;10401 Roselle Street, Suite 400;San Diego;CA;92121
email;internet:[EMAIL PROTECTED]
title:Chief Engineer
tel;work:858-332-0700 x118
tel;fax:858-332-0709
url:http://www.spacemicro.com
version:2.1
end:vcard

_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to