gpt4 book ai didi

python - 在 python (matplotlib) 中优雅地停止(而不是暂停)动画情节

转载 作者:太空宇宙 更新时间:2023-11-03 18:20:01 28 4
gpt4 key购买 nike

我正在一个进程中运行动画分散。一切工作正常,除了当我想退出一切时抛出异常。

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'

有没有办法做完全相同的事情但避免异常?或者在某个地方捕获这个异常?

最佳答案

您可以很容易地捕获该异常:

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

但是,一旦你捕获了那个,你就会得到一个新的(至少在我的系统上):

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

我找不到任何方法来抑制它。您可以做的只是终止子进程,而不是尝试向其发送关闭信号:

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

这不像通过队列发送某些内容那么优雅(并且不允许在子进程中进行任何额外的清理,假设您需要它),但不会抛出任何异常。

关于python - 在 python (matplotlib) 中优雅地停止(而不是暂停)动画情节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24299159/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com