Discussion:
[Matplotlib-users] dynamic update in TkAgg ? (more)
Gary Pajer
2004-05-23 03:01:49 UTC
Permalink
I've been trying to figure out how to do an dynamic update in TkAgg
without
success. Anyone have any pointers?
I'm trying to recreate the functionality of the Pmw.Blt stripchart.
-gary
I guess I should be a little more specific. The part I'm having trouble
with is the dynamic update. As a step along the way, I've got a gui with a
button that just replots some data slightly altered from the original.

If I use FigureCanvasTkAgg.show (schematically speaking) it will replot, but
just once. That is, my button's callback routine contains a loop that tries
to change the data (via set_ydata followed by ....show()) several times in a
row. If I click the button, the data updates, but only once. I click it
again, it the data updates once. I remove the loop, the data updates once.
This strikes me as odd. How should the graphics window know or care if I'm
in a python loop or not?

I'm thinking that a well-placed call to
canvas.get_tk_widget.update_idletasks() should do the job, but that hasn't
worked for me either.

Aside: having played with anim.py I'm concerned about speed. It seems that
the speed of anim.py is limited by my system, not by the call to
gtk.timeout_add(). I might be back asking about a solution that runs faster
... perhaps a lower level solution. (Pmw.Blt works fast enough.) Hmm... I
just tried anim.py again, and it won't run. I've just upgraded to 0.54.
Odd ... it opens a Tk window. I'll try that again later after I reboot.
I'm on WinXP.

Comment: I don't have a handle at all on how the graphics system is
organized. For example, what is a figure manager? When do I use it? I
don't seem to need it, but there it is, and some of the examples use it.
Looking through the docstrings I find myself going in circles. Maybe I'm
digging too deeply for my own good. Maybe you developer types might add to
your to-do list a description of the stucture of the graphics system.

thanks again,
gary

btw, for every task other than animation, matplotlib is the bomb. great
job.
John Hunter
2004-05-24 14:22:42 UTC
Permalink
Gary> I guess I should be a little more specific. The part I'm
Gary> having trouble with is the dynamic update. As a step along
Gary> the way, I've got a gui with a button that just replots some
Gary> data slightly altered from the original.

Gary> If I use FigureCanvasTkAgg.show (schematically speaking) it
Gary> will replot, but just once. That is, my button's callback
Gary> routine contains a loop that tries to change the data (via
Gary> set_ydata followed by ....show()) several times in a row.
Gary> If I click the button, the data updates, but only once. I
Gary> click it again, it the data updates once. I remove the
Gary> loop, the data updates once. This strikes me as odd. How
Gary> should the graphics window know or care if I'm in a python
Gary> loop or not?

99% of the time, should only call show once per script -
http://matplotlib.sourceforge.net/faq.html#SHOW. If you want to
update the plot after changing some data, you should draw
canvas.draw(), as in examples/dynamic_demo.py. If you are still
having troubles after trying this, send me an attached script and I'll
take a look.

Gary> I'm thinking that a well-placed call to
Gary> canvas.get_tk_widget.update_idletasks() should do the job,
Gary> but that hasn't worked for me either.

Gary> Aside: having played with anim.py I'm concerned about speed.
Gary> It seems that the speed of anim.py is limited by my system,
Gary> not by the call to gtk.timeout_add(). I might be back
Gary> asking about a solution that runs faster ... perhaps a lower
Gary> level solution. (Pmw.Blt works fast enough.) Hmm... I just
Gary> tried anim.py again, and it won't run. I've just upgraded
Gary> to 0.54. Odd ... it opens a Tk window. I'll try that again
Gary> later after I reboot. I'm on WinXP.

I am also interested in improving performance here. My goal is to
extend agg canvas so that portions of the canvas can be updated, eg a
vertical stip, to support things like strip charts. We have a project
at the hospital that I'm working on where we'd like to write a simple
AD data collection framework using matplotlib for the display, so I've
been mulling over the kinds of changes that need to be made. Do you
know now what kinds of updates you need to make? Eg, do you have
lines and you know you only need to update the screen for xlim between
points a and b?

Gary> Comment: I don't have a handle at all on how the graphics
Gary> system is organized. For example, what is a figure manager?
Gary> When do I use it? I don't seem to need it, but there it is,
Gary> and some of the examples use it. Looking through the
Gary> docstrings I find myself going in circles. Maybe I'm
Gary> digging too deeply for my own good. Maybe you developer
Gary> types might add to your to-do list a description of the
Gary> stucture of the graphics system.

It's absolutely a need and it's on my mental list of things to do.
There have been so many other areas that have required work and I
haven't made the time to generate adequate documentation. For the
near term I'd like to concentrate on getting all the install problems
ironed out and getting some documentation going.

Gary> btw, for every task other than animation, matplotlib is the
Gary> bomb. great job.

Thanks!
JDH
Todd Miller
2004-05-24 14:31:53 UTC
Permalink
Post by Gary Pajer
I've been trying to figure out how to do an dynamic update in TkAgg
without
success. Anyone have any pointers?
I'm trying to recreate the functionality of the Pmw.Blt stripchart.
-gary
I guess I should be a little more specific. The part I'm having trouble
with is the dynamic update. As a step along the way, I've got a gui with a
button that just replots some data slightly altered from the original.
If I use FigureCanvasTkAgg.show (schematically speaking) it will replot, but
just once. That is, my button's callback routine contains a loop that tries
to change the data (via set_ydata followed by ....show()) several times in a
row. If I click the button, the data updates, but only once. I click it
again, it the data updates once. I remove the loop, the data updates once.
This strikes me as odd. How should the graphics window know or care if I'm
in a python loop or not?
I'm thinking that a well-placed call to
canvas.get_tk_widget.update_idletasks() should do the job, but that hasn't
worked for me either.
Aside: having played with anim.py I'm concerned about speed. It seems that
the speed of anim.py is limited by my system, not by the call to
gtk.timeout_add(). I might be back asking about a solution that runs faster
... perhaps a lower level solution. (Pmw.Blt works fast enough.) Hmm... I
just tried anim.py again, and it won't run. I've just upgraded to 0.54.
Odd ... it opens a Tk window. I'll try that again later after I reboot.
I'm on WinXP.
Comment: I don't have a handle at all on how the graphics system is
organized. For example, what is a figure manager? When do I use it? I
don't seem to need it, but there it is, and some of the examples use it.
Looking through the docstrings I find myself going in circles. Maybe I'm
digging too deeply for my own good. Maybe you developer types might add to
your to-do list a description of the stucture of the graphics system.
thanks again,
gary
btw, for every task other than animation, matplotlib is the bomb. great
job.
I tried porting anim.py to TkAgg this morning and got it basically
working. There are two things that might account for the trouble you've
been having:

1. With TkAgg, at least for now, you have to call the figure manager
show() method with each cycle rather than the canvas draw() method.

2. The Tk timed event system requires re-registering the handler with
each cycle.

Performance was better than I thought it would be but still kinda slow.

Hope this helps,
Todd


Todd Miller <***@stsci.edu>
John Hunter
2004-05-25 15:13:28 UTC
Permalink
Todd> I tried porting anim.py to TkAgg this morning and got it
Todd> basically working. There are two things that might account
Todd> for the trouble you've been having:

Todd> 1. With TkAgg, at least for now, you have to call the
Todd> figure manager show() method with each cycle rather than the
Todd> canvas draw() method.

Would it be possible to reorganize tkagg so that a call to canvas.draw
also triggers a blit so that the interface could be more consistent
across backends?

Todd> 2. The Tk timed event system requires re-registering the
Todd> handler with each cycle.

Or you can do something like this

def updatefig(*args):
updatefig.count += 1
lines[0].set_ydata(X[:,updatefig.count%60])
manager.show()
return updatefig.count
updatefig.count=-1

while 1:
cnt = updatefig()
if cnt==100: break

Todd> Performance was better than I thought it would be but still
Todd> kinda slow.

I profiled this because it was slower than I expected. Turns out that
there is a huge performance hit in the changes I made to Text to
handle arbitrary rotations (a lot of time spent in Matrix getitem,
multiply, etc...). With text I could get only 5 frames per second;
w/o text I get 13 fps. The good news is that it will be easy to
optimize away most of the text based performance hit using more
efficient matrix operations and caching.

This can likely be improved further by using collections for drawing
markers in the line class.

Gary: did Todd's example help you enough to speed you on your way?

JDH
Gary Pajer
2004-05-25 16:01:30 UTC
Permalink
Post by John Hunter
Gary: did Todd's example help you enough to speed you on your way?
JDH
Well... I might say "yes", but you did put that word "speed" in there :)

If I run his code, it updates 1.5 frame per second. If I change the two
calls to

manager.canvas._tkcanvas.after(100, updatefig)

to

manager.canvas._tkcanvas.after(1, updatefig)

there is no difference in the speed.
FWIW, I'm on an 850MHz WinXP. IIRC, I get the same performance under linux
on the same machine.

You got five frames per second? When you say you improved performance
"without text" do you mean that you didn't label the axes?

Aside: I see that he calls show() in each iteration, yet John says show()
should only be called once per script. Todd seems
to be on top of this, so I'll take his word as good. Todd uses a figure
manager. I can copy that code, but I don't know what I'm doing with it. I
don't know what a figure manager does.

Finally, I'm not sure what he meant by "re-registering the handler with each
cycle". Does this mean call ....after() ?

Oh ... one last thing, and maybe this is somehow relevant ... Todd's
Post by John Hunter
invalid command name "18438384callit"
while executing
"18438384callit"
("after" script)

...after which I'm dumped into python (interactive prompt).

-gary
John Hunter
2004-05-25 16:29:16 UTC
Permalink
Gary> Well... I might say "yes", but you did put that word
Gary> "speed" in there :)

I'm attaching a modified text.py which uses caching. These changes
alone give be about a 4x increase in frame rate. I reran the profiler
after these changes and there are some other changes that will provide
marginal increases, but this one was the sitting duck. Just drop it
into site-packages/matplotlib/

Gary> You got five frames per second? When you say you improved
Gary> performance "without text" do you mean that you didn't label
Gary> the axes?

My machine is a good bit faster than yours, which accounts for the
difference in frame rates. But you should still get significantly
better performance with the attached file.

Gary> Aside: I see that he calls show() in each iteration, yet
Gary> John says show() should only be called once per script.
Gary> Todd seems to be on top of this, so I'll take his word as
Gary> good. Todd uses a figure manager. I can copy that code,
Gary> but I don't know what I'm doing with it. I don't know what
Gary> a figure manager does.

You don't need to call show. Todd, in fact calls "manager.show()"
which is a different function than
matplotlib.backends.backend_tkagg.show. I would like to unify the
interface so that all backends call canvas.draw, but that is not
possible right now.

Gary> Finally, I'm not sure what he meant by "re-registering the
Gary> handler with each cycle". Does this mean call ....after() ?

He means that it is not enough to call
manager.canvas._tkcanvas.after(100, updatefig) just once in your
script, but that you have to call it for each update you want. By
putting the call in updatefig itself, he insures that the cycle
continues. Just another way of doing

while 1:
updatefig()
sleep(sometime)


Gary> Oh ... one last thing, and maybe this is somehow relevant
invalid command name "18438384callit"
Gary> while executing "18438384callit" ("after" script)

Gary> ...after which I'm dumped into python (interactive prompt).

I get this too when I try and close the figure while it's running, but
I don't think it's relevant to the problem at hand. I think it just
has to do with inelegantly handling a close.

Here's the new text.py
Todd Miller
2004-05-25 21:11:30 UTC
Permalink
Post by John Hunter
Todd> I tried porting anim.py to TkAgg this morning and got it
Todd> basically working. There are two things that might account
Todd> 1. With TkAgg, at least for now, you have to call the
Todd> figure manager show() method with each cycle rather than the
Todd> canvas draw() method.
Would it be possible to reorganize tkagg so that a call to canvas.draw
also triggers a blit so that the interface could be more consistent
across backends?
I've been on leave a lot today but I'll take a look at this either this
evening or tomorrow morning.

Todd
Todd Miller
2004-05-25 21:35:25 UTC
Permalink
Post by Todd Miller
Post by John Hunter
Todd> I tried porting anim.py to TkAgg this morning and got it
Todd> basically working. There are two things that might account
Todd> 1. With TkAgg, at least for now, you have to call the
Todd> figure manager show() method with each cycle rather than the
Todd> canvas draw() method.
Would it be possible to reorganize tkagg so that a call to canvas.draw
also triggers a blit so that the interface could be more consistent
across backends?
I've been on leave a lot today but I'll take a look at this either this
evening or tomorrow morning.
This turned out to be really easy so now canvas.draw triggers a blit and
functions more like the other backends. It's in CVS. I also found an
extraneous draw() so performance should be better, perhaps 2x.

Cheers,
Todd
Peter Groszkowski
2004-05-25 22:30:17 UTC
Permalink
Hi:

The following script:

#!/usr/bin/env python
from matplotlib.matlab import *

figure(1)
plot([0],[0])
show()


gives this traceback:

Traceback (most recent call last):
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_gtkagg.py",
line 75, in callback
self.draw()
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_gtkagg.py",
line 42, in draw
agg.draw()
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_agg.py",
line 299, in draw
self.figure.draw(self.renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/figure.py", line
128, in draw
for a in self.axes: a.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axes.py", line 603,
in draw
self.xaxis.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axis.py", line 463,
in draw
tick.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axis.py", line 130,
in draw
if self.label1On: self.label1.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/text.py", line 202,
in draw
ismath=self.is_math_text())
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_agg.py",
line 203, in draw_text
self._renderer.draw_text(
OverflowError: float too large to convert

If I remember correctly, there was a similar issue when 0.53 came out.
--
Peter Groszkowski Gemini Observatory
Tel: +1 808 974-2509 670 N. A'ohoku Place
Fax: +1 808 935-9235 Hilo, Hawai'i 96720, USA
matthew arnison
2004-05-26 00:59:15 UTC
Permalink
The call to tick_right() seems to produce different behaviour in 0.54.

Instead of moving the tick labels to the right of the plot, it instead
now moves the labels to just inside the left side of the plot. This it to
the right of where they were, but not nearly as useful as the original
behaviour. :)

See the attached screenshot generated from two_scales.py

Otherwise, congratulations on another excellent matplotlib release!

Cheers,
Matthew.
John Hunter
2004-05-26 15:17:20 UTC
Permalink
matthew> The call to tick_right() seems to produce different
matthew> behaviour in 0.54. Instead of moving the tick labels to
matthew> the right of the plot, it instead now moves the labels to
matthew> just inside the left side of the plot. This it to the
matthew> right of where they were, but not nearly as useful as the
matthew> original behaviour. :)

matthew> See the attached screenshot generated from two_scales.py

Hi Matthew, these are my favorite bug fixes - just a single character
change! In matplotlib.axis.YAxis._get_text2 (on or around line 311),
change

t = Text(x=0, y=loc,

to

t = Text(x=1, y=loc,

Should cure what ails you.

matthew> Otherwise, congratulations on another excellent
matthew> matplotlib release!

Thanks! Not without a few roadbumps along the way....

JDH
John Hunter
2004-05-26 15:12:14 UTC
Permalink
Peter> Hi: The following script:

Peter> #!/usr/bin/env python from matplotlib.matlab import *

Peter> figure(1) plot([0],[0]) show()

Thanks, Peter, for alerting me to this problem. I'm now adding this
script and several other instances of plotting constants in a variety
of guises to the unit testing scripts. I think the following fix will
work for you. Replace matplotlib.axes.Axes.add_line with

def add_line(self, l):
"Add a line to the list of plot lines"
self._set_artist_props(l)

xdata = l.get_xdata()
ydata = l.get_ydata()
if l.get_transform() != self.transData:
xys = self._get_verts_in_data_coords(
l.get_transform(), zip(xdata, ydata))
self.update_datalim(xys)
else:
# the data are already using the data coord system - no
# transforms necessary
minx, maxx = min(xdata), max(xdata)
miny, maxy = min(ydata), max(ydata)
if minx==maxx:
minx -= 1
maxx += 1

if miny==maxy:
miny -= 1
maxy += 1

corners = ( (minx, miny), (maxx, maxy) )

self.update_datalim(corners)

l.set_clip_box(self.bbox)
self._lines.append(l)

Passes my tests...

JDH
Peter Groszkowski
2004-05-28 03:20:30 UTC
Permalink
Post by John Hunter
Peter> #!/usr/bin/env python from matplotlib.matlab import *
Peter> figure(1) plot([0],[0]) show()
Thanks, Peter, for alerting me to this problem. I'm now adding this
script and several other instances of plotting constants in a variety
of guises to the unit testing scripts. I think the following fix will
work for you. Replace matplotlib.axes.Axes.add_line with
"Add a line to the list of plot lines"
self._set_artist_props(l)
xdata = l.get_xdata()
ydata = l.get_ydata()
xys = self._get_verts_in_data_coords(
l.get_transform(), zip(xdata, ydata))
self.update_datalim(xys)
# the data are already using the data coord system - no
# transforms necessary
minx, maxx = min(xdata), max(xdata)
miny, maxy = min(ydata), max(ydata)
minx -= 1
maxx += 1
miny -= 1
maxy += 1
corners = ( (minx, miny), (maxx, maxy) )
self.update_datalim(corners)
l.set_clip_box(self.bbox)
self._lines.append(l)
Passes my tests...
Just a note that the version of the above method in 0.54.1 still gives me:

Traceback (most recent call last):
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_gtkagg.py",
line 75, in callback
self.draw()
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_gtkagg.py",
line 42, in draw
agg.draw()
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_agg.py",
line 296, in draw
self.figure.draw(self.renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/figure.py", line
130, in draw
for a in self.axes: a.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axes.py", line 607,
in draw
self.xaxis.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axis.py", line 463,
in draw
tick.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/axis.py", line 130,
in draw
if self.label1On: self.label1.draw(renderer)
File "/usr/lib/python2.2/site-packages/matplotlib/text.py", line 209,
in draw
ismath=self.is_math_text())
File
"/usr/lib/python2.2/site-packages/matplotlib/backends/backend_agg.py",
line 200, in draw_text
self._renderer.draw_text(
OverflowError: float too large to convert

When doint plot([0],[0]).
The above substitute fixes the problem though...
--
Peter Groszkowski Gemini Observatory
Tel: +1 808 974-2509 670 N. A'ohoku Place
Fax: +1 808 935-9235 Hilo, Hawai'i 96720, USA
John Hunter
2004-05-26 17:09:54 UTC
Permalink
Todd> This turned out to be really easy so now canvas.draw
Todd> triggers a blit and functions more like the other backends.
Todd> It's in CVS. I also found an extraneous draw() so
Todd> performance should be better, perhaps 2x.

Yep, I'm getting about 20fps on my system now. Much improved.

Gary, I'm uploading a zip file which has the new matplotlib python
code. AFAIK, all the changes were made at the python level (right
Todd?) so you should just be able to unzip this in your site-packages
dir to try the new code. Let me know if it works, and what kind of
performance you are getting now.

http://nitace.bsd.uchicago.edu:8080/files/share/matplotlib-0.54.1a.zip

JDH
Todd Miller
2004-05-26 18:29:21 UTC
Permalink
Post by John Hunter
Todd> This turned out to be really easy so now canvas.draw
Todd> triggers a blit and functions more like the other backends.
Todd> It's in CVS. I also found an extraneous draw() so
Todd> performance should be better, perhaps 2x.
Yep, I'm getting about 20fps on my system now. Much improved.
Gary, I'm uploading a zip file which has the new matplotlib python
code. AFAIK, all the changes were made at the python level (right
Todd?)
Yes, the changes were pure Python and limited to backend_tkagg.py.

Todd
Post by John Hunter
so you should just be able to unzip this in your site-packages
dir to try the new code. Let me know if it works, and what kind of
performance you are getting now.
http://nitace.bsd.uchicago.edu:8080/files/share/matplotlib-0.54.1a.zip
JDH
--
Todd Miller <***@stsci.edu>
Gary Pajer
2004-05-28 13:51:18 UTC
Permalink
----- Original Message -----
Post by John Hunter
Todd> This turned out to be really easy so now canvas.draw
Todd> triggers a blit and functions more like the other backends.
Todd> It's in CVS. I also found an extraneous draw() so
Todd> performance should be better, perhaps 2x.
Yep, I'm getting about 20fps on my system now. Much improved.
Gary, I'm uploading a zip file which has the new matplotlib python
code. AFAIK, all the changes were made at the python level (right
Todd?) so you should just be able to unzip this in your site-packages
dir to try the new code. Let me know if it works, and what kind of
performance you are getting now.
http://nitace.bsd.uchicago.edu:8080/files/share/matplotlib-0.54.1a.zip
JDH
I took out a wristwatch and timed it instead of guessing. I get three
frames per second. It's about 4x from where we started, but still slow. I
guess I'm just underpowered, although a couple of years ago this was a
powerhouse. It seems that matplotlib may not be suited to this task. I
don't think it should take 2 GHz just to power a stripchart.

I've got new hardware coming this summer. I get whatever IT gives me (until
I can find funds to buy my own), so I don't know what I'll be getting.
We'll see what happens.

I have another question, but I'll start a new thread for that ...

-gary
John Hunter
2004-05-28 14:24:59 UTC
Permalink
Gary> I took out a wristwatch and timed it instead of guessing. I
Gary> get three frames per second. It's about 4x from where we
Gary> started, but still slow. I guess I'm just underpowered,
Gary> although a couple of years ago this was a powerhouse. It
Gary> seems that matplotlib may not be suited to this task. I
Gary> don't think it should take 2 GHz just to power a stripchart.

I agree. The current design of matplotlib doesn't really support this
kind of use because it redraws the entire figure every time and does
too much duplicate work at the python level. It shouldn't be too hard
to add some specialized functions for agg that support strip charts.
I've been planning to do it because we have a need for it here, and
there is some general on c.l.python for this kind of plotting feature
in python.

So I can start mulling over the design, can you tell me what kinds of
real time updates you need - only solid lines or arbitrary symbols
like 'o' too? Anything else besides line plots?

I'm envisioning some extension code that talks directly to the data
source and to the agg backend, updating only part of the canvas. The
blitting functions for GTK/WX/Tk Agg would have to be extended to blit
only a region of the canvas.

JDH
Stephen Roderick
2004-05-28 18:48:41 UTC
Permalink
Post by John Hunter
I agree. The current design of matplotlib doesn't really support this
kind of use because it redraws the entire figure every time and does
too much duplicate work at the python level. It shouldn't be too hard
to add some specialized functions for agg that support strip charts.
I've been planning to do it because we have a need for it here, and
there is some general on c.l.python for this kind of plotting feature
in python.
So I can start mulling over the design, can you tell me what kinds of
real time updates you need - only solid lines or arbitrary symbols
like 'o' too? Anything else besides line plots?
I'm envisioning some extension code that talks directly to the data
source and to the agg backend, updating only part of the canvas. The
blitting functions for GTK/WX/Tk Agg would have to be extended to blit
only a region of the canvas.
We'd also be interested in updates to real-time graph capabilities.
We've just started examining Python + wxPython as a platform for
control of some of our robotic systems. I've gotten a real-time bar
graph running now, but it's awfully inefficient. I modified the basic
dynamic_demo_wx.py file to update regularly, and at a forced 10 FPS it
locks out the wxPython interface on my dual 2 GHZ Mac G5. No way it
should do that ...

We'd also be interested in strip charts, mostly line based. We'd want
to do multiple lines per chart. A capability to move through time, or
zooming, might be useful, but certainly not necessary in a first rev
(just mentioning it for now).

For bar graphs, we have to update at a given rate (typically up to
about 25Hz), with different colors per bar (I have yet to do this part
in the example I'm working on - think of multilpe temperatures being
displayed, and different colors indicating different zones, per bar;
nominal, caution, danger).

Having said all that, we're currently using wxPython, and I don't yet
understand how AGG fits in the picture with matplotlib. :-(

TIA
Stephen

John Hunter
2004-05-28 14:56:50 UTC
Permalink
Gary> I took out a wristwatch and timed it instead of guessing. I
Gary> get three frames per second. It's about 4x from where we
Gary> started, but still slow. I guess I'm just underpowered,
Gary> although a couple of years ago this was a powerhouse. It
Gary> seems that matplotlib may not be suited to this task. I
Gary> don't think it should take 2 GHz just to power a stripchart.

One more comment here, mainly for Todd.

Todd, I get 34 FPS on anim.py with GTKAgg and only 21 FPS with the
anim_tk.py, where both scripts are doing the same thing. The profiler
reveals a good chunk of the time is in

103 2.300 0.022 2.300 0.022 tkagg.py:4(blit)

This may be a tk limitation, but I just wanted to point it out to you
in case there are any optimizations you can apply to that function.

I'll include the anim_tk.py I'm using for profiling below.

Cheers,
JDH

#!/usr/bin/env python2.3
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.matlab
import Tkinter as Tk
import matplotlib.numerix as numerix

fig = matplotlib.matlab.figure(1)
ind = numerix.arange(60)
x_tmp=[]
for i in range(100):
x_tmp.append(numerix.sin((ind+i)*numerix.pi/15.0))

X=numerix.array(x_tmp)
lines = matplotlib.matlab.plot(X[:,0],'o')

manager = matplotlib.matlab.get_current_fig_manager()
def updatefig(*args):
updatefig.count += 1
lines[0].set_ydata(X[:,updatefig.count%60])
manager.canvas.draw()
return updatefig.count
updatefig.count=-1


manager.show()
import time
tstart = time.time()
while 1:
cnt = updatefig()
if cnt==100: break




print 'FPS', 100.0/(time.time() - tstart)
Todd Miller
2004-05-28 18:35:02 UTC
Permalink
Post by John Hunter
Gary> I took out a wristwatch and timed it instead of guessing. I
Gary> get three frames per second. It's about 4x from where we
Gary> started, but still slow. I guess I'm just underpowered,
Gary> although a couple of years ago this was a powerhouse. It
Gary> seems that matplotlib may not be suited to this task. I
Gary> don't think it should take 2 GHz just to power a stripchart.
One more comment here, mainly for Todd.
Todd, I get 34 FPS on anim.py with GTKAgg and only 21 FPS with the
anim_tk.py, where both scripts are doing the same thing. The profiler
reveals a good chunk of the time is in
103 2.300 0.022 2.300 0.022 tkagg.py:4(blit)
This may be a tk limitation, but I just wanted to point it out to you
in case there are any optimizations you can apply to that function.
I tried a few things, but I didn't find anymore performance blunders
so barring the kind of optimization Perry mentioned, I think we're
stuck. I think most of the time is going into Tk_PhotoPutBlock.
Post by John Hunter
I'll include the anim_tk.py I'm using for profiling below.
I only got 11-12 FPS (for tkagg) on a 1.7 Ghz Pentium-IV...

Todd
Perry Greenfield
2004-05-26 15:40:07 UTC
Permalink
We are trying to have setup.py handle X11-based Tkinter on Mac OS X
(to date that is the only Tkinter we use). Does anyone out there
use Tkagg with the Aqua-based Tkinter on Mac OS X? We are unclear
as to whether the Aqua version is really useful yet.

Thanks, Perry Greenfield
Matt Newville
2004-05-26 16:00:01 UTC
Permalink
Post by Perry Greenfield
We are trying to have setup.py handle X11-based Tkinter on Mac OS X
(to date that is the only Tkinter we use). Does anyone out there
use Tkagg with the Aqua-based Tkinter on Mac OS X? We are unclear
as to whether the Aqua version is really useful yet.
TkAgg with Aqua-based Tkinter works for me on Mac OS X. (That's
with matplotlib 0.54 -- I haven't tried the latest CVS with fixes
for dynamic updates, but am happy to hear it will be faster!).

The Aqua-based Tkinter is not great, and I would be perfectly happy
using X11-based Tkinter. I simply installed the Tkinter with the
MacPython and its PackageManager. Is X11-based Tkinter available in
such a package, or does it require a source build?? A source build
would be OK with me, but might make it difficult to distribute apps.

--Matt Newville <newville @ cars.uchicago.edu>
Andrew Straw
2004-05-26 10:17:07 UTC
Permalink
Post by Matt Newville
Post by Perry Greenfield
We are trying to have setup.py handle X11-based Tkinter on Mac OS X
(to date that is the only Tkinter we use). Does anyone out there
use Tkagg with the Aqua-based Tkinter on Mac OS X? We are unclear
as to whether the Aqua version is really useful yet.
It's been a little while since I've gotten down-and-dirty on OS X, but
as of a year or so ago, I was continually frustrated with Tkinter on OS
X because of apparent weird little bugs, but I never felt sufficiently
on top of Tkinter to really believe they were bugs with Tkinter or with
me. Anyhow, I switched to wx, and have never been happier. It looks
great on Aqua, is totally cross-platform, and XRCed rocks!
Post by Matt Newville
TkAgg with Aqua-based Tkinter works for me on Mac OS X. (That's
with matplotlib 0.54 -- I haven't tried the latest CVS with fixes
for dynamic updates, but am happy to hear it will be faster!).
The Aqua-based Tkinter is not great, and I would be perfectly happy
using X11-based Tkinter. I simply installed the Tkinter with the
MacPython and its PackageManager. Is X11-based Tkinter available in
such a package, or does it require a source build?? A source build
would be OK with me, but might make it difficult to distribute apps.
Fink sticks to the X environment, so I'm 99% sure that if you install
their Tkinter it'll run on X11. I think this probably means installing
Python from fink, too. So you'd have 2 Pythons: Apple's and fink's (in
/sw/bin/python, I guess). If you want to distribute apps as a packaged
.dmg that someone can just download and run on an OS X system, the fink
route seems a little, uh, challenging.

Good luck!
Andrew
Perry Greenfield
2004-05-28 15:59:34 UTC
Permalink
John Hunter writes
Post by John Hunter
One more comment here, mainly for Todd.
Todd, I get 34 FPS on anim.py with GTKAgg and only 21 FPS with the
anim_tk.py, where both scripts are doing the same thing. The profiler
reveals a good chunk of the time is in
103 2.300 0.022 2.300 0.022 tkagg.py:4(blit)
This may be a tk limitation, but I just wanted to point it out to you
in case there are any optimizations you can apply to that function.
I'll include the anim_tk.py I'm using for profiling below.
Cheers,
JDH
I do believe it is a limitation of the tk api (which the
blitting code uses) that makes writing to pixels of the
tk window comparatively slow. It is possible to come up
with a tk interface using tkinter3000( aka wck) and some
hairy code to write directly to the window buffer. Eric
Jones has done this for the chaco implementation. Porting
it to matplotlib would take some work (how much I'm not
quite sure). It is isn't important to us right now so
we aren't going to do it for some time. If someone else
is interested they are welcome to. It does mean writing
a C or C++ implementation for each platform (i.e., X, win32,
aqua). I know that the blitting can be improved by more
than an order of magnitude in this way.

Perry
Loading...