On Fri, Jan 27, 2012 at 5:54 AM, Jerzy Karczmarczuk <
> Benjamin Root answers my query concerning user-generated events :
> > To answer your question, take a look at how pick_event() is declared
> > in backend_bases.py:
> > def pick_event(self, mouseevent, artist, **kwargs):
> > ...
> > self.callbacks.process(s, event)
> > The function that "fires" the event is "self.callbacks.process(s,
> > event)", where "self" is the figure canvas.
> Dear Ben, thank you, but this is not exactly my problem. I don't want to
> call the callback myself, since the event should be "fired" from within
> a callback. I should have been more precise. Let's distil the problem.
> [This is a part of my current teaching...] I did already what you
> suggest here...
> Imagine an animation, which consists in generating a trajectory, segment
> after segment (say, of a planet). Classically this is a loop, but when
> it runs, the rest of the program is blocked. So, instead, the code
> behaves as a Python generator, generates just one segment, and that's
> all. But it "yields" something, it posts an event, put it in a queue,
> and somebody else, the mainloop() or similar, pops it off the queue and
> re-launches the callback. (With generators, it calls the .next()). No
> timers, as in Timer or Funct animations...
> It must be "decentralized", no recursive calls. My callback from time to
> time creates another planet, or destroys an existent, and there are
> simultaneous trajectories on the screen, several concurrent events in
> the queue. And the system should remain reactive, interpret buttons,
> sliders, etc.
> I know how to do this by hand, how to write my own event loop, declare a
> queue, and how to add to my private "virtual" event handling also the
> callbacks of mouse events. But this is an overkill, I repeat the
> functionalities which are already there, the event queue in particular.
> I did it with wx. But Matplotlib protects the user from the concrete
> back-end, and I want to protect my students as well, so I look for a
> "GUI-neutral" solution.
I'm not sure if this matches your use case, but have you looked into using
a coroutine. (I only recently learned about them---see presentation slides
linked on this page <http://www.dabeaz.com/coroutines/>. So obviously I'm
going out of my way to find a use case :)
I've attached a simple example below.
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
line, = ax.plot(0, 0, 'o-')
i = 1
y0 = yield
x = np.hstack((line.get_xdata(), i))
y = np.hstack((line.get_ydata(), y0))
i += 1
plotdata = datalistener()
# initialize the coroutine
y = raw_input('enter data point: ')