Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib exit after animation

I am writing a program in Python, using matplotlib to (among other things) run an animation showing a numerical solution to the time-dependent Schrodinger Equation.

Everything is working fine, but once an animation has finished running, I would like the window it was in to close itself. My way of doing this (shown below) works, but exceptions are thrown up which I cant seem to catch. It works fine for what I need it to do, but the error looks very messy.

I have an alternative method which works without throwing an error, but requires the user to manually close the window (unacceptable for my purposes). Can someone please point out what I am doing wrong, or suggest a better option?

A simplified version of the relevant parts of my code follows:

from matplotlib import animation as ani
from matplotlib import pyplot as plt

multiplier = 0
def get_data():         # some dummy data to animate
    x = range(-10, 11)
    global multiplier
    y = [multiplier * i for i in x]
    multiplier += 0.005
    return x, y

class Schrodinger_Solver(object):
    def __init__(self, xlim = (-10, 10), ylim = (-10, 10), num_frames = 200):

        self.num_frames = num_frames
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111, xlim = xlim, ylim = ylim)
        self.p_line, = self.ax.plot([], [])

        self.ani = ani.FuncAnimation(self.fig, self.animate_frame,
                                     init_func = self.init_func,
                                     interval = 1, frames = self.num_frames,
                                     repeat = False, blit = True)

        plt.show()

    def animate_frame(self, framenum):
        data = get_data()
        self.p_line.set_data(data[0], data[1])

        if framenum == self.num_frames - 1:
            plt.close()
        # closes the window when the last frame is reached,
        # but exception is thrown. Comment out to avoid the error,
        # but then the window needs manual closing

        return self.p_line,

    def init_func(self):
        self.p_line.set_data([], [])
        return self.p_line,

Schrodinger_Solver()

I am running Python 2.7.2 on windows 7, with matplotlib 1.1.0

Thanks in advance

EDIT: exception and traceback as follows:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 495, in callit
    func(*args)
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 116, in _on_timer
    TimerBase._on_timer(self)
  File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 1092, in _on_timer
    ret = func(*args, **kwargs)
  File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 315, in _step
    still_going = Animation._step(self, *args)
  File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 177, in _step
    self._draw_next_frame(framedata, self._blit)
  File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 197, in _draw_next_frame
    self._post_draw(framedata, blit)
  File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 220, in _post_draw
    self._blit_draw(self._drawn_artists, self._blit_cache)
  File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 240, in _blit_draw
    ax.figure.canvas.blit(ax.bbox)
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 244, in blit
    tkagg.blit(self._tkphoto, self.renderer._renderer, bbox=bbox, colormode=2)
  File "C:\Python27\lib\site-packages\matplotlib\backends\tkagg.py", line 19, in blit
    tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
TclError: this isn't a Tk application

Traceback (most recent call last):
  File "C:\Python27\quicktest.py", line 44, in <module>
    Schrodinger_Solver()
  File "C:\Python27\quicktest.py", line 26, in __init__
    plt.show()
  File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 139, in show
    _show(*args, **kw)
  File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 109, in __call__
    self.mainloop()
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 69, in mainloop
    Tk.mainloop()
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 325, in mainloop
    _default_root.tk.mainloop(n)
AttributeError: 'NoneType' object has no attribute 'tk'

I can catch the second exception, the AttributeError, by a small change:

try: plt.show()
except AttributeError: pass

but the first part, the TclError, remains no matter what I try

like image 676
user2546207 Avatar asked Jul 03 '13 11:07

user2546207


People also ask

How do you stop a plot in Python?

Use the block = False inside show : plt.

What is PLT show block false?

plt.show(block=False) #this creates an empty frozen window. _ = raw_input("Press [enter] to continue.") if __name__ == '__main__': main()


1 Answers

I had the same problem a few minutes before... The reason was a very low interval-value in FuncAnimation. Your code tries to update the graphics evere 1 millisecond - quite fast! (1000 fps might not be needed). I tried interval=200 and the error was gone...

HTH

like image 139
OBu Avatar answered Oct 19 '22 01:10

OBu