Backend neutral idle event won't repeat

Hi,

I’m writing a script to plot data being read from a serial connection in real time. I’m trying to use an idle_event callback to continually read the incoming data and plot it. The problem is that the callback is only getting invoked once. I found this page: http://www.scipy.org/Cookbook/Matplotlib/Animations, which suggests using backend-specific stuff. This is intended to be a quick-and-dirty thing though so I was really hoping to avoid that. Here’s my code:

def OnIdle(event):
global xData
global yData
data = ReadSerialData()
if data != None:
yData.append(data)
if len(yData) > GRAPH_WINDOW_SIZE:
del yData[0]
else:
xData.append(len(xData))
line.set_xdata(xData)
line.set_ydata(yData)
pylab.draw()
# end if data != None

end OnIdle

if name == ‘main’:
pylab.ion()

fig = pylab.figure()
ax = fig.add_subplot(1,1,1)
line = ax.add_line(pylab.Line2D([], []))
ax.set_ylim(0, 100)
ax.set_xlim(0, GRAPH_WINDOW_SIZE)
fig.canvas.mpl_connect('idle_event', OnIdle)

pylab.show()

end name == ‘main

Oh btw, I’m positive that ReadSerialData is not blocking and that it’s making it through the whole idle handler. I’m running on 64 bit Linux with Python 2.6. According to --verbose-helpful, I’m using matplotlib version 0.98.5.2 and GTKAgg version 2.14.1. Am I doing something wrong or do I really need to go backend-specific?

Thanks,
Mark

Wriing a GUI neutal idle event handler is not easy -- I've spent some
time on it but crashed and burned on tk -- but my guess is that the
problem you are having in your code is that GTK expects you to return
True is you want the func to be called again. As soon as you return
False the event handler is terminated. You return nothing, which is
None, which is False. A simple "return True" may cure what ails you
vis-a-vis gtk. But pylab animation is not supported, so I suggest
that you code to your GUI of choice for animation until we get a
proper GUI neutral animation event API.

JDH

···

On Sat, Aug 1, 2009 at 12:05 PM, Mark Rubelmann<mrubelmann@...287...> wrote:

Hi,

I'm writing a script to plot data being read from a serial connection in
real time. I'm trying to use an idle_event callback to continually read the
incoming data and plot it. The problem is that the callback is only getting
invoked once. I found this page:
http://www.scipy.org/Cookbook/Matplotlib/Animations, which suggests using
backend-specific stuff. This is intended to be a quick-and-dirty thing
though so I was really hoping to avoid that. Here's my code:

I should phrase this last bit differently: I would like to support
this, and spent a fair amount of time trying to get this working
properly across backends. I think it *does* work on GTK and WX. I
encountered some problems in tkagg: since tk does not have a native
idle event loop that I could wrap, I tried to use python threading to
implement it, and ran into problems with cross thread signal handling
(including losing CTRL-C and some strange on-exit behavior) so
commented out the code, and have not attempted qt or macosx. I think
it would be great if we could abstract the idle handler and timeout
handler across the GUIs so that mpl animation would be easier, but to
date this has eluded me. So in the meantime, I would stick to the API
of the GUI of your choice until we can get proper support for this as
an mpl event.

JDH

···

On Sun, Aug 2, 2009 at 8:08 AM, John Hunter<jdh2358@...287...> wrote:

Wriing a GUI neutal idle event handler is not easy -- I've spent some
time on it but crashed and burned on tk -- but my guess is that the
problem you are having in your code is that GTK expects you to return
True is you want the func to be called again. As soon as you return
False the event handler is terminated. You return nothing, which is
None, which is False. A simple "return True" may cure what ails you
vis-a-vis gtk. But pylab animation is not supported, so I suggest
that you code to your GUI of choice for animation until we get a
proper GUI neutral animation event API.

Thanks for the reply John. Not quite the answer I was looking for though… :wink: I tried your suggestion of returning True but it didn’t solve the problem. Oh well, not the end of the world. Being a die-hard KDE user, I started trying to get things working with Qt. I got my animation working but thus far haven’t been able to catch key press events. My guess is that I’m just missing something about how it’s supposed to be done so I’ll probably figure it out.

Thanks again,
Mark

···

On Sun, Aug 2, 2009 at 9:17 AM, John Hunter <jdh2358@…287…> wrote:

On Sun, Aug 2, 2009 at 8:08 AM, John Hunter<jdh2358@…287…> wrote:

Wriing a GUI neutal idle event handler is not easy – I’ve spent some

time on it but crashed and burned on tk – but my guess is that the

problem you are having in your code is that GTK expects you to return

True is you want the func to be called again. As soon as you return

False the event handler is terminated. You return nothing, which is

None, which is False. A simple “return True” may cure what ails you

vis-a-vis gtk. But pylab animation is not supported, so I suggest

that you code to your GUI of choice for animation until we get a

proper GUI neutral animation event API.

I should phrase this last bit differently: I would like to support

this, and spent a fair amount of time trying to get this working

properly across backends. I think it does work on GTK and WX. I

encountered some problems in tkagg: since tk does not have a native

idle event loop that I could wrap, I tried to use python threading to

implement it, and ran into problems with cross thread signal handling

(including losing CTRL-C and some strange on-exit behavior) so

commented out the code, and have not attempted qt or macosx. I think

it would be great if we could abstract the idle handler and timeout

handler across the GUIs so that mpl animation would be easier, but to

date this has eluded me. So in the meantime, I would stick to the API

of the GUI of your choice until we can get proper support for this as

an mpl event.

JDH

You should be able to use mpl key press events even while embedding in qt

/Users/jdhunter/Library/Preferences/Aquamacs Emacs/customizations.el

···

On Sun, Aug 2, 2009 at 9:39 AM, Mark Rubelmann<mrubelmann@...287...> wrote:

Thanks for the reply John. Not quite the answer I was looking for
though.... :wink: I tried your suggestion of returning True but it didn't solve
the problem. Oh well, not the end of the world. Being a die-hard KDE user,
I started trying to get things working with Qt. I got my animation working
but thus far haven't been able to catch key press events. My guess is that
I'm just missing something about how it's supposed to be done so I'll
probably figure it out.

oops posted in the wrong thing from my buffer. Meant to post this link

http://matplotlib.sourceforge.net/search.html?q=codex+key_press_event

···

On Sun, Aug 2, 2009 at 10:35 AM, John Hunter<jdh2358@...287...> wrote:

On Sun, Aug 2, 2009 at 9:39 AM, Mark Rubelmann<mrubelmann@...287...> wrote:

Thanks for the reply John. Not quite the answer I was looking for
though.... :wink: I tried your suggestion of returning True but it didn't solve
the problem. Oh well, not the end of the world. Being a die-hard KDE user,
I started trying to get things working with Qt. I got my animation working
but thus far haven't been able to catch key press events. My guess is that
I'm just missing something about how it's supposed to be done so I'll
probably figure it out.

You should be able to use mpl key press events even while embedding in qt

John Hunter wrote:

Wriing a GUI neutal idle event handler is not easy -- I've spent some
time on it but crashed and burned on tk

> I think

it would be great if we could abstract the idle handler and timeout
handler across the GUIs so that mpl animation would be easier, but to
date this has eluded me.

Maybe getting away from the Idle event approach would be the way to go. I've done a lot of (non-MPL) wx work, including animations, and NEVER found a use for the idle event. For animation work in wx, using a wx.Timer, and often a call to wx.Yield seems to generally be the way to go. Perhaps this same approach could be done on the other back ends as well.

As for idle events, I've found them to be useless because you get lots of them when you don't need it, and may not get them when you do. In wx at least, an Idle event is triggered when the event loop _becomes_ empty. That means that when the user is moving the mouse and there is no mouse_move event handler, you get this huge string of idle events. However, if the user is doing nothing for a bit, you get one event, then nothing until the user does something again.

I can see the appeal of an Idle event -- there are all sorts of things you might want to do when the app is "idle", but the reality is that what you really want to know is when the app is _going to be_ idle for a bit, and there is no way to know that (at least not without Guido's time machine, anyway...).

I've lost track of what problems you're trying to solve with idle events, but maybe an abstraction of a timer system would be a more robust approach, for animations, anyway.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...259...

John Hunter wrote:

Wriing a GUI neutal idle event handler is not easy – I’ve spent some

time on it but crashed and burned on tk

I think

it would be great if we could abstract the idle handler and timeout

handler across the GUIs so that mpl animation would be easier, but to

date this has eluded me.

Maybe getting away from the Idle event approach would be the way to go.

I’ve done a lot of (non-MPL) wx work, including animations, and NEVER

found a use for the idle event. For animation work in wx, using a

wx.Timer, and often a call to wx.Yield seems to generally be the way to

go. Perhaps this same approach could be done on the other back ends as well.

As for idle events, I’ve found them to be useless because you get lots

of them when you don’t need it, and may not get them when you do. In wx

at least, an Idle event is triggered when the event loop becomes

empty. That means that when the user is moving the mouse and there is no

mouse_move event handler, you get this huge string of idle events.

However, if the user is doing nothing for a bit, you get one event, then

nothing until the user does something again.

I can see the appeal of an Idle event – there are all sorts of things

you might want to do when the app is “idle”, but the reality is that

what you really want to know is when the app is going to be idle for a

bit, and there is no way to know that (at least not without Guido’s time

machine, anyway…).

I’ve lost track of what problems you’re trying to solve with idle

events, but maybe an abstraction of a timer system would be a more

robust approach, for animations, anyway.

-Chris

I think that’s a fantastic idea, especially if you can go abstract and make it work for all the backends.

I’ve lost track of what problems you’re trying to solve with idle
events, but maybe an abstraction of a timer system would be a more
robust approach, for animations, anyway.

If you’re referring to my problem, I need to read data from a
serial connection which then drives an animated graph. Going as fast
as possible is fine but honestly, it’s overkill. Strictly using timers
would work in both situations.

-Mark

···

On Mon, Aug 3, 2009 at 1:01 PM, Christopher Barker <Chris.Barker@…259…> wrote: