I apologize since I have open another ticket before on a related topic. Thanks to the answers I got now I can be more specific. I have also received some solutions based on Tkinter, but I would like to solve my problems with events and loops.
The particular case I am dealing with is as follows: I have an array of arrays. I want matplotlib to plot the first element of it, allow me to press one key (with an associated event), and the program plots the second array, same behaviour, and so on.
As a quick example:
import matplotlib.pyplot as plt
import numpy as np
# Define the event
def ontype(event):
if event.key == '1':
print 'It is working'
plt.clf()
# Create figure an connect the event to it
fig=plt.figure(figsize=(16,8))
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
# Loop
for element in xrange(10):
#This mimicks the "array of arrays" generating a random array in each loop
vector = np.random.random(10)
plt.plot(vector)
plt.show()
I would expect to get a first plot (the first time the loop runs), and that it is left open until I press 1. However, what I get is an figure with the ten vectors plotted, and when I press 1 the figure is cleared and it says "It is working" via terminal. I need the program to plot the first one, and move to the next element once a key has been pressed. Any hint on this? What am I doing wrong?
Thank you guys!
EDIT:
Please keep in mind that in principle, the structure of the program can not be varied, and the for loop is needed to compute different things before plotting anything. Hence, the program should go
def ontype(event):
define event
Some stuff
elements = array of arrays
for element in elements:
do more stuff
plot element and "stay" in this plot untill any event key is pressed. And then, go to the next element in elements and do the same
EDIT 2:
I think I didn't explained myself properly and the kind of data might have been missunderstood. In my case, I am reading a huge table of data, and each line is a different source. Whay I am trying to plot is the information of the columns. I am a physicist, so I don't have much knowledge about stylish programming or anything. The problem is...if there is no way to do this with a for loop, could anyone explain me how to do this kind of work without it?
This next block is what does what you want with the
for
loop.Your
for
loop goes into the functionugly_math
, and what you want plotted is what goes afteryield
. see What does the "yield" keyword do in Python? . In short,yield
turns a function with a loop into a generator factory.is then a generator. When you call
fun.next()
it will run the functionugly_math
until it hits theyield
. It will then return the value yielded (in this example,np.random.random
). The next time you callfun.next()
it will pick up where it left off in the loop and run until it hitsyield
again. Hence it does exactly what you want.Then borrowing heavily from Holger:
The
cid_dict
is there so that we can remove the call-back after we have exhausted the generator.We can wrap this all up into a class as such
This is used as such:
Any iterable will work with a bit of finessing:
This amused me enough I saved it as a gist.
You do not need a loop. Redraw the new plots in the event function
ontype
with the commandfig.canvas.draw()
.