Doug Holton wrote:
I still need a scrolling plot canvas, too. I was looking at adapting
wxPyPlot but there are too many changes that would be needed, so I'm
starting to think about a new control and maybe it could be integrated
with wxPyPlot later.
I'm not sure I'd start from scratch..there's some good stuff in
wxPyPlot. However, whether you cut& paste code from wxPyPlot into yours,
or alter wxPyPlot doesn't make much difference.
It would be like a seismograph or heart beat monitor. The scrolling
plot should be "live" - keep scrolling even when no new data is being
sent from separate threads or processes. You should be able to use a
scrollbar to scroll back and see earlier data.
It should subclass wxScrolledWindow AND wxTimer, or else use an internal
thread to update the plot similar to wxpython/lib/throbber.py.
Use wxTimer. There's no reason to use threads for this kind of thing.
Throbber.py should probably use a wxTimer as well, but it was written
that way first, and serves as a good demo for how to post events from
threads to update your GUI. Where you should use threads is to run a
computation or something asyncronously, and then post events form that
thread to update the GUI.
This brings up my suggestion for how to structure your scrolling
canvas...
Rather than have the updateing of the plot built in, you should build a
plotwindow that has some sort of update method. For your use, you would
either subclass this and an an auto-update, or just use it as a member
of your new class that does the auto updateing. In fact, the way I've
re-written wxPyPlot could alrady support most of this (though it can use
some cleaning up).
I'm also not sure I'd use wxScrolledWindow. If you do that, you'll get a
lot of re-painting as you scroll. If it's something that Paints fast,
that's just fine, but if not, it can get ugly. What I'd like to see is a
way to indicate what part of your time series you want to see, and then
call your update method and re-draw the image. This is why I didn't use
wxSCrolledWindow in my Float Canvas. Rather, you can drag the image
where you want it, and it only re-draws when you are done dragging.
My version of wxPyPlot supports most of what you need. Update the data,
and them call the Zoom method. The one real problem I see is that the
way I have it structured now, you can re-draw the data fast, if the axis
havn't changed. For your purposes, however, you'll need to re-draw at
least the X-axis (time) as you scroll. When we tried updating the plot
by re-calculating and re-drawing the entire axis each time, it was way
too slow.
What I'd be inclined to do is break the wxPyPlot Draw() method into
components:
draw X axis
draw X axis labels
draw Y axis
draw Y axis labels
draw grid
draw legend
draw data
I've re-worked wxPyPlot a little more, so that it used an extra buffer
for the Axis. NOw, when you re-draw the data, it blits the axes buffer
tot he main buffer, then draws the data on top of it. THis way you can
have grid lines, etc. It seems to work well, except for two things:
1) I had to add and extra wxClientDC.DrawBitmap call in the Draw()
method, or the whole image didn't display in the demo. If you covered
and uncovered the window, it does display, so the off screen bitmap is
correct. Wierd. (Linux, python2.3 wxPythonGTK 2.2.4.2 ) Does anyone else
get this behaviour?
2) Printing has probably been screwed up. I havn't tested that yet.
You might want to make the legend a separate bitmap as well, then you
could draw it once, and always put it back on top of the plot after
For the demo, I'm using three simple "models" that run in their own
threads and send data to the plot: sin(time), and the current mouse X &
Y positions on the screen (wxGetMousePosition).
How far have you gotten with your demo? Do you have something to post?
I've enclosed my latest wxPyPlot.
-Chris
wxPyPlot2.py (55.7 KB)
···
--
Christopher Barker, Ph.D.
Oceanographer
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov