2014-06-19 4 views
1

나는 프로세스에서 애니메이션 산포를 실행 중입니다. 모든 것을 끝내고 싶을 때 예외가 발생한다는 것을 제외하고는 모든 것이 잘 작동합니다. 예를 들어파이썬 (matplotlib)에서 애니메이션 플롯을 정상적으로 중지 (일시 중지하지 않음)

import multiprocessing as mp 
import time 
from collections import deque 

def start_colored_scores(nb_channels): 
    q = mp.Queue() 
    process = mp.Process(target=colored_scores,args=(q,nb_channels,4000)) 
    process.start() 
    return process,q 

def colored_scores(q,nb_channels,size): 
    import matplotlib.pyplot as plt 
    import matplotlib.animation as animation 
    fig, axes = plt.subplots(nrows=nb_channels,ncols=1,sharex=True,sharey=True) 
    plt.axis([-1.0,1.0,-1.0,1.0]) 
    scats = [axe.scatter([0], [0], c="white", s=size) for axe in axes] 
    def animate(i): 
     scores = q.get() 
     if scores is None : # this is the external signal saying things should stop 
      plt.close() 
      return [axe.scatter([0], [0], c="white", s=size) for axe in axes] 
     scats = [] 
     for score,axe in zip(scores,axes): 
      score = max(min(1,1-score),0) 
      scats.append(axe.scatter([0], [0], c=(1-score,0,score), s=size)) 
     return scats 
    ani = animation.FuncAnimation(fig, animate, interval=1, blit=True) 
    plt.show() 

, 이것이 잘 작동 :

_,q = start_colored_scores(2) 
x = 0 
right = 1 
time_start = time.time() 
while time.time()-time_start < 5: 
    if right==1 and x>1.0: 
     x = 1.0 
     right = -1 
    if right==-1 and x<0.0: 
     x = 0.0 
     right = 1 
    x+=right*0.02 
    q.put([x,1-x]) 
    time.sleep(0.02) 
q.put(None) # indicating I do not need plotting anymore 

print "this is printed ... exception in the process ?" 

행동은 내가 예상대로입니다 : 없앤다 표시하고 5 초 동안 애니메이션되어, 다음 프로그램이 계속됩니다.

AttributeError: 'NoneType' object has no attribute 'tk' 

똑같은하지만 예외를 방지 할 수있는 방법이 있나요 : 유일한 문제가 발생되는 예외 (나는 과정에서 추측) 말하는 것입니다? 아니면이 예외를 어딘가에 잡으려고?

+1

전체 스택 추적을 추가 할 수 있습니까? – Nathaniel

답변

1

당신은 아주 쉽게 그 예외를 잡을 수 :

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ 
    return self.func(*args) 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 536, in callit 
    func(*args) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 141, in _on_timer 
    TimerBase._on_timer(self) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1203, in _on_timer 
    ret = func(*args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 876, in _step 
    still_going = Animation._step(self, *args) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 735, in _step 
    self._draw_next_frame(framedata, self._blit) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 755, in _draw_next_frame 
    self._post_draw(framedata, blit) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 778, in _post_draw 
    self._blit_draw(self._drawn_artists, self._blit_cache) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 798, in _blit_draw 
    ax.figure.canvas.blit(ax.bbox) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 353, in blit 
    tkagg.blit(self._tkphoto, self.renderer._renderer, bbox=bbox, colormode=2) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/tkagg.py", line 20, in blit 
    tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array)) 
TclError: this isn't a Tk application 

내가 할 수있는 : 한, 당신은 (적어도 내 시스템에) 새로운 하나를 얻을 캐치 일단, 그러나

def colored_scores(q,nb_channels,size): 
    import matplotlib.pyplot as plt 
    import matplotlib.animation as animation 
    fig, axes = plt.subplots(nrows=nb_channels,ncols=1,sharex=True,sharey=True) 
    plt.axis([-1.0,1.0,-1.0,1.0]) 
    scats = [axe.scatter([0], [0], c="white", s=size) for axe in axes] 
    def animate(i): 
     scores = q.get() 
     if scores is None : # this is the external signal saying things should stop 
      plt.close() 
      return [axe.scatter([0], [0], c="white", s=size) for axe in axes] 
     scats = [] 
     for score,axe in zip(scores,axes): 
      score = max(min(1,1-score),0) 
      scats.append(axe.scatter([0], [0], c=(1-score,0,score), s=size)) 
     return scats 
    ani = animation.FuncAnimation(fig, animate, interval=1, blit=True) 
    try: 
     plt.show() 
    except AttributeError: # This will supress the exception 
     pass 

을 그걸 억누를 방법이 없다. 당신이 무엇을 할 수 있는지, 단지 하위 프로세스를 종료하는 대신 종료에에게 신호를 보내려고한다 :

proc,q = start_colored_scores(2) 
x = 0 
right = 1 
time_start = time.time() 
while time.time()-time_start < 5: 
    if right==1 and x>1.0: 
     x = 1.0 
     right = -1 
    if right==-1 and x<0.0: 
     x = 0.0 
     right = 1 
    x+=right*0.02 
    q.put([x,1-x]) 
    time.sleep(0.02) 
#q.put(None) # indicating I do not need plotting anymore 
proc.terminate() 

이 큐를 통해 무언가를 보내는만큼 우아하지 않습니다 (그리고 추가 깨끗한 허용하지 않습니다 당신이 그것을 원한다고 가정한다면), 예외를 던지지는 않을 것입니다.

관련 문제