2013-07-03 91 views
9

我正在用Python编写一个程序,使用matplotlib(除其他外)运行一个动画,显示依赖于时间的薛定谔方程的数值解。matplotlib动画后退出

一切工作正常,但一旦动画完成运行,我想它是关闭自己的窗口。我这样做的方式(如下所示)有效,但是例外情况已经出现,我似乎无法理解。它适用于我需要的功能,但错误看起来非常混乱。

我有一个替代方法,它不会引发错误,但需要用户手动关闭窗口(对我而言不可接受)。有人能指出我做错了什么,或者建议更好的选择吗?

我的代码的相关部分的简化版本如下:

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() 

我在Windows 7上运行的Python 2.7.2,与matplotlib提前1.1.0

感谢

编辑: 异常和回溯如下:

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' 

我能赶上第二个例外,AttributeError的,通过一个小的变化:

try: plt.show() 
except AttributeError: pass 

但第一部分,TclError,仍然不管我怎么努力

+0

有什么异常?还请包括追踪! –

回答

0

尝试:

if framenum == self.num_frames - 1: 
    exit() 

它适用于我...

+0

这是通过完全关闭程序来实现的。我需要一种自己关闭窗口的方式是因为我希望在动画窗口关闭后发生其他事情(其他动画,计算,以前计算的动画之间的比较)。关闭该程序就是为了达到这个目的。让这个过程自动化的一点是,我可以让我的计算机用一大堆计算器来突破,并在我回来的时候完成。如果我必须在每个动画之后重新开始,那么我可以坚持我所拥有的。 – user2546207

+0

想要知道我想要什么,如果将以下内容添加到代码底部,那么我想要的是第一个动画运行,然后关闭,然后运行第二个动画: 'multiplier = 0 ; Schrodinger_Solver()' – user2546207

5

几分钟前我有同样的问题...原因是非常低的interval-FuncAnimation的值。你的代码试图更新图形evere 1毫秒 - 相当快! (可能不需要1000fps)。我试图interval=200和错误不见了......

HTH

+0

为什么这是一个问题,但?在出现错误之前,我可以使用多少间隔值?看起来很奇怪,允许有一些任意限制。我试图绘制出尽可能快的实时计算结果(手动确保在'animate'函数返回前至少经过0.1秒),所以我不想插入人工延迟。 –