13

My code produces a number of plots from data using matplotib and I would like to be able to scroll forwards and backwards through them in a live demonstration (maybe by pressing the forwards and backwards keys or using the mouse). Currently I have to save each one as an image separately and then use a separate image viewer to scroll through them. Is there any way of doing this entirely from within python?

3
  • Is the time required to generate the plots live too long for you to do just that? I.e. press a button -> generate a plot -> show it and so on. Commented Aug 22, 2013 at 20:45
  • @AleksanderLidtke I can generate them live but how do I scroll forwards and backwards through the plots I have created? Commented Aug 22, 2013 at 20:46
  • callbacks. See matplotlib.org/users/event_handling.html . As it stands this question is too broad. Commented Aug 22, 2013 at 21:07

1 Answer 1

24

An easy way to achieve that is storing in a list a tuple of the x and y arrays and then use a handler event that picks the next (x,y) pair to be plotted:

import numpy as np import matplotlib.pyplot as plt # define your x and y arrays to be plotted t = np.linspace(start=0, stop=2*np.pi, num=100) y1 = np.cos(t) y2 = np.sin(t) y3 = np.tan(t) plots = [(t,y1), (t,y2), (t,y3)] # now the real code :)  curr_pos = 0 def key_event(e): global curr_pos if e.key == "right": curr_pos = curr_pos + 1 elif e.key == "left": curr_pos = curr_pos - 1 else: return curr_pos = curr_pos % len(plots) ax.cla() ax.plot(plots[curr_pos][0], plots[curr_pos][1]) fig.canvas.draw() fig = plt.figure() fig.canvas.mpl_connect('key_press_event', key_event) ax = fig.add_subplot(111) ax.plot(t,y1) plt.show() 

In this code I choose the right and left arrows to iterate, but you can change them.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks much jabaldonedo--- your example is now in my project and so I can confirm for others that it works. In my case key_event is a closure within a closure inside a decorator. I do not fathom the cause--- so help me it's not erroneous punctuation on the end of the previous line--- but I kept getting "global name curr_pos not defined", notwithstanding the fact it is clearly defined by curr_pos = 0. I opted for a solution in the form if not hasattr(key_event, "curr_pos"): key_event.curr_pos = 0 in place of global curr_pos. I would use key_event.__dict__={} to reset if needed.
Thank you, this worked perfectly for me! I tried to comment out fig.canvas.draw() and it still works. Maybe it is not needed?
I don't understand how the namespace works in this example. I understand why curr_pos needs to be a global variable, but why then does key_event have access to the plots list and the ax axes instance?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.