I am facing issues with the implementation of the method animation from the class wave bellow. The animation method aims to create an animation of a wave propagation. I do not want that the animation method modify the state instance variable u of the Wave object, and because of that I am trying to create a local variable u inside the method animation. Nevertheless, I do not know how to pass the local variable u from the animation method for the animate function that is defined inside the animation method. In the way that I tried to implement, from my conception, the local variable u of the method animation should be a king of global variable for the animate method (that is defined inside the animation method). But, this assumption is cleary wrong, otherwise I would not get an error. As a complementary information the error I am getting is: UnboundLocalError: local variable 'u' referenced before assignment.
I will be glad if someone indicate to me the way for the implementation that I want.
thanks in advance
class Wave(object):
def __init__(self, phenomenon):
'''
nx: Number of spatial grid points
dx: Distance between any pair of adjacent grid points
nt: Number of steps in time
nu: Diffusion coefficient
dt: Value of the step in time
c: wave velocity
u: grid vector of the wave
'''
if phenomenon == 'convection':
self.phenomenon = phenomenon
self.nx = 81
self.dx = 2.0/(self.nx - 1) # Distance between any pair of adjacent grid
self.nt = 100
self.dt = 0.002
self.c = 3
self.x = numpy.linspace(0,4,self.nx)
self.u = numpy.ones(self.nx)
self.lbound = numpy.where(self.x >= 0.5)
self.ubound = numpy.where(self.x <= 1.0)
self.bounds = numpy.intersect1d(self.lbound[0], self.ubound[0])
self.u[self.bounds] = 2
if phenomenon == 'diffusion':
...
if phenomenon == 'burgers':
...
def _convection(self, u):
un = u.copy()
u[1:] = un[1:] - self.c*self.dt/self.dx*(un[1:] - un[:-1])
u[0] = 1.0
return u
def integration(self):
if self.phenomenon == 'convection':
for n in range(1,self.nt):
self.u = self._convection(u=self.u)
if self.phenomenon == 'diffusion':
...
if self.phenomenon == 'burgers':
...
def animation(self):
fig = plt.figure()
ax = plt.axes(xlim=(0,4), ylim=(0,3))
ax.grid()
line, = ax.plot([], [], 'o-', lw=2)
time_template = 'time = %.2fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
def init():
line.set_data([], [])
time_text.set_text('')
return line, time_text
x = self.x
u = self.u.copy()
def animate(i):
if self.phenomenon == 'convection':
u = self._convection(u=u)
if self.phenomenon == 'diffusion':
...
if self.phenomenon == 'burgers':
...
line.set_data(x,u)
time_text.set_text(time_template % (i*self.dt))
return line, time_text
anim = animation.FuncAnimation(fig, animate, frames=500, init_func=init, interval=10, blit=True)
plt.show()
EDIT
Complete trace error:
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 754, in
_draw_next_frame
self._draw_frame(framedata) File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 1049, in
_draw_frame
self._drawn_artists = self._func(framedata, *self._args) File "wave.py", line 201, in animate
un = u.copy() UnboundLocalError: local variable 'u' referenced before assignment 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 754, in
_draw_next_frame
self._draw_frame(framedata) File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 1049, in
_draw_frame
self._drawn_artists = self._func(framedata, *self._args) File "wave.py", line 201, in animate
un = u.copy() UnboundLocalError: local variable 'u' referenced before assignment
When you capture a variable with a closure in Python, you are not allowed to assign to it. If Python sees you assign to it, then it isn't allowed to be captured from the enclosing scope; it must be a new function-local variable (local to your animate function). But since you're trying to use the captured u to initialize it, you need that u's value, but in this context Python has decided that u must be local to animate, so it isn't looking at animate's enclosing scope. That's why you're getting that error.
A simple way to get around that in your case is just to define animate as
def animate(i, u=u):
...
This explicitly passes a copy of u into animate.
Related
So, I'm trying to animate some pixels moving around a static image using FuncAnimation. The static image itself is 256x256 and the objects moving around are essentially a brightly colored pixel. In the end i'd like for the animation to go indefinitely or until I stop it but thats besides the point. Right now I'd like to get things moving first.
The static image in question is this one (for this example anyways).
The code below is a simple class consisting of a location and color. When i spawn it or move it i make sure to record the previous pixel color so the object doesnt leave 'tracks' sort of speak.
class Prey:
def __init__(self, color = [255, 0, 255]) -> None:
self.color = color
self.x = None
self.y = None
def set_spawn(self, world):
self.x = random.randint(0, 256)
self.y = random.randint(0, 256)
while np.array_equal(world[self.x][self.y], [65, 105, 225]):
self.x = random.randint(0, 256)
self.y = random.randint(0, 256)
prev_pix = world[self.x, self.y]
return prev_pix
def move(self, world, x, y):
if not np.array_equal(world[x][y], [65, 105, 225]):
prev_pix = ((self.x, self.y), world[x][y])
self.x = x
self.y = y
return prev_pix
And below here I actually try to animate the damn thing.
def load_map(wname):
bgr_world = cv2.imread(wname)
rgb_world = cv2.cvtColor(bgr_world, cv2.COLOR_BGR2RGB)
return rgb_world
world = load_map('m3.png')
fig = plt.figure('lifesim')
im = plt.imshow(world, animated=True)
p1 = Prey()
def movement(*args):
x1, y1, prev_pix1 = p1.move(world, p1.x+1, p1.y) #i'm trying to get it to move down (when it actually works ill make sure it doesnt go OOB)
ppxy, pp = prev_pix1
ppx, ppy = ppxy
world[ppx][ppy] = pp
world[x1][y1] = p1.color
im.set_array(world)
return world,
def init_game(world):
x0, y0, prev_pix0 = p1.set_spawn(world) #The spawn is random, so i just overwrote it here so i can test
prev_pix0 = world[110, 100]
x0, y0 = (110, 100)
p1.x = 110
p1.y = 100
world[x0][y0] = p1.color
ani = animation.FuncAnimation(fig, movement, blit=True)
plt.show()
def main():
init_game(world)
if __name__ == "__main__":
main()
And when the code gets eventually executed, i get the following error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Python39\lib\site-packages\matplotlib\backends\_backend_tk.py", line 241, in resize
self.resize_event()
File "C:\Python39\lib\site-packages\matplotlib\backend_bases.py", line 1767, in resize_event
self.callbacks.process(s, event)
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 229, in process
self.exception_handler(exc)
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 81, in _exception_printer
raise exc
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 224, in process
func(*args, **kwargs)
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1275, in _on_resize
self._init_draw()
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1719, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1747, in _draw_frame
self._drawn_artists = sorted(self._drawn_artists,
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1748, in <lambda>
key=lambda x: x.get_zorder())
AttributeError: 'numpy.ndarray' object has no attribute 'get_zorder'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Python39\lib\tkinter\__init__.py", line 814, in callit
func(*args)
File "C:\Python39\lib\site-packages\matplotlib\backends\_backend_tk.py", line 253, in idle_draw
self.draw()
File "C:\Python39\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 9, in draw
super(FigureCanvasTkAgg, self).draw()
File "C:\Python39\lib\site-packages\matplotlib\backends\backend_agg.py", line 407, in draw
self.figure.draw(self.renderer)
File "C:\Python39\lib\site-packages\matplotlib\artist.py", line 41, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "C:\Python39\lib\site-packages\matplotlib\figure.py", line 1870, in draw
self.canvas.draw_event(renderer)
File "C:\Python39\lib\site-packages\matplotlib\backend_bases.py", line 1759, in draw_event
self.callbacks.process(s, event)
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 229, in process
self.exception_handler(exc)
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 81, in _exception_printer
raise exc
File "C:\Python39\lib\site-packages\matplotlib\cbook\__init__.py", line 224, in process
func(*args, **kwargs)
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 975, in _start
self._init_draw()
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1719, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1747, in _draw_frame
self._drawn_artists = sorted(self._drawn_artists,
File "C:\Python39\lib\site-packages\matplotlib\animation.py", line 1748, in <lambda>
key=lambda x: x.get_zorder())
AttributeError: 'numpy.ndarray' object has no attribute 'get_zorder'
I'm not sure what I'm doing wrong here since I'm completely new to matplotlibs animation modules... The mistake is probably blisteringly obvious but I just can't see it.
I have been trying to animate a polar plot in which I have a one degree wide wedge sweep all the way around the plot in a circle. I tried using the code below, but for some reason, it gives me the error AttributeError: 'NoneType' object has no attribute 'canvas'. I was trying to initialize the wedge as a rectangle patch that starts off on the right side of the plot and increases in x (angle), so I thought I should update the x-coordinate in the animate function, but for some reason, whenever I return patch (the rectangle) from animation, it gives me an error. Any tips? Thanks!
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.patches import Rectangle
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
_, rlim = ax.get_ylim()
patch = Rectangle((0,0), np.radians(1), rlim)
def init():
ax.add_patch(patch)
return patch,
def animate(i):
patch.set_xy((np.radians(i), 0))
return patch,
ani = animation.FuncAnimation(fig, animate, frames=360, interval=30, blit=True)
plt.show()
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib64/python3.6/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/usr/lib64/python3.6/tkinter/__init__.py", line 749, in callit
func(*args)
File "/usr/lib64/python3.6/site-packages/matplotlib/backends/_backend_tk.py", line 114, in _on_timer
TimerBase._on_timer(self)
File "/usr/lib64/python3.6/site-packages/matplotlib/backend_bases.py", line 1187, in _on_timer
ret = func(*args, **kwargs)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1449, in _step
still_going = Animation._step(self, *args)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1169, in _step
self._draw_next_frame(framedata, self._blit)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1189, in _draw_next_frame
self._post_draw(framedata, blit)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1212, in _post_draw
self._blit_draw(self._drawn_artists, self._blit_cache)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1229, in _blit_draw
bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
AttributeError: 'NoneType' object has no attribute 'canvas'
I'm trying to animate a piece of text in matplotlib, in order to make some educational videos. However, I'm having trouble with setting text in motion.
I've tried to use FuncAnimation (as I did for animating lines), and defining the anchor of that text as a pair of moving coordinates. Here's what I've tried:
def data_gen(): #Data generator. Gives me the anchor.
counter = 0
x0 = data_gen.x0
while counter < 1000:
counter+=1
x0-=0.09
yield x0,(1-counter*0.05)
data_gen.x0=1
def animate_text(data): #Here is where I try to tell my code to refresh
#only the coordinates of the text.
x0,y0 = data
text_sample = ax.text(x0,y0,'text here',transform=ax.transAxes,
fontsize=12, color='black',fontstyle='oblique',family='serif')
return text_sample
#animation part:
ani = animation.FuncAnimation(fig,animate_text,data_gen,blit=True,
interval=50,repeat = False)
plt.show()
However, I get this:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\matplotlib\cbook\__init__.py", line 387,
in process
proxy(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\cbook\__init__.py", line 227,
in __call__
return mtd(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1026, in
_start
self._init_draw()
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1750, in
_init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1777, in
_draw_frame
for a in self._drawn_artists:
TypeError: 'Text' object is not iterable
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\matplotlib\cbook\__init__.py", line 387,
in process
proxy(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\cbook\__init__.py", line 227,
in __call__
return mtd(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1308, in
_handle_resize
self._init_draw()
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1750, in
_init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Python27\lib\site-packages\matplotlib\animation.py", line 1777, in
_draw_frame
for a in self._drawn_artists:
TypeError: 'Text' object is not iterable
Does anybody know how can I solve that?
In FuncAnimation documentation you can read:
func must return an iterable of all artists that were modified or
created
"iterable" means that animate_text() has to return list or tuple with elements - even if you have only one element:
return (text_sample,)
My problem is following:
I'm taking a data from files and want to make an animation of four plots at the same time: two colourbars and two lines.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
import sys
begin = float(sys.argv[1])
end = float(sys.argv[2])
dataCl = np.loadtxt("file1.txt")
dataSS = np.loadtxt("file2.txt")
datajSR = np.loadtxt("file3.txt")
ibegin = 0
iend = 0
for i in range(len(dataCl[:,0])):
if np.abs(dataCl[i,0] - begin) < 1e-9:
ibegin = i
iend = i
while abs(dataCl[i,0] - end) >= 1e-9:
iend = iend + 1
i = i + 1
break
fig = plt.figure()
f, axarr = plt.subplots(2, 2)
temp = np.zeros((10,10))
Qs = axarr[0,0].imshow(temp,cmap = plt.cm.OrRd)
El = axarr[0,1].imshow(temp,cmap = plt.cm.OrRd)
SS, = axarr[1,0].plot([],[])
jSR, = axarr[1,1].plot([],[])
def init():
Qs.set_array(temp)
El.set_array(temp)
SS.set_data([],[])
jSR.set_data([],[])
return Qs,El,SS,jSR,
def animate(i):
a = 0
b = 0
dataQ = np.zeros((10,10))
dataE = np.zeros((10,10))
for j in range(100):
if b >= 10:
a = a + 1
b = 0
dataQ[a][b] = dataCl[i,2*j + 1]
dataE[a][b] = dataCl[i,2*(j+1)]
b = b + 1
Qs.set_array(dataQ)
El.set_array(dataE)
SS.set_data(dataSS[ibegin:ibegin+i,0],dataSS[ibegin:ibegin+i,1])
jSR.set_data(datajSR[ibegin:ibegin+i,0],datajSR[ibegin:ibegin+i,1])
return Qs,El,SS,jSR,
ani = anim.FuncAnimation(fig, animate, init_func = init, frames = iend-ibegin,interval=25, blit=True)
plt.show()
After running it shows these messages:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
return self.func(*args)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 236, in resize
self.show()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 239, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_agg.py", line 421, in draw
self.figure.draw(self.renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/figure.py", line 904, in draw
self.canvas.draw_event(renderer)
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1544, in draw_event
self.callbacks.process(s, event)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 262, in process
proxy(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 192, in __call__
return mtd(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 273, in _end_redraw
self._post_draw(None, self._blit)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 220, in _post_draw
self._blit_draw(self._drawn_artists, self._blit_cache)
File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 235, in _blit_draw
a.axes.draw_artist(a)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 2008, in draw_artist
assert self._cachedRenderer is not None
AssertionError
I cannot find a mistake in my code ;(
The error message might be backend and platform specific. As the error message seems to point to the blitting mechanism, you might want to try setting blit=False in FuncAnimation. Also, you might try some other backend to see if the problem persists. (Knowing your platform and matplotlib version might also help.)
Update: If setting blit=False, trying another backend, and updating matplotlib does not help, then a few suggestions:
Try to see manually if you code works with the initial data (init(); animate(0); fig.savefig("/tmp/test.png")) - if it throws an error, there is a static plotting problem to fix.
Now you initialize the plot twice (first in the code, then in init), you can take one away (e.g. do not define init_func)
Initializing the plots with [],[] leaves the scale uninitialized. You should probably use set_ylim, set_xlim with the plots and vmin, vmax keywords with the imshow images when you initialize them. (This could possibly have something to do with the exception you get!)
I am running an animated scatter in a process. Everything is working fine, except that an exception is throw when I want to exit everything.
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()
For example, this is working fine:
_,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 ?"
The behavior is as I expect : scatters are displayed and animated for 5 seconds, then the program continues. The only issue is that an exception is thrown (I guess in the process) saying :
AttributeError: 'NoneType' object has no attribute 'tk'
Is there a way to do the exact same thing but avoiding the exception ? Or to catch this exception somewhere ?
You can catch that exception pretty easily:
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
However, once you get catch that one, you get a new one (at least on my system):
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
I can't find any way to supress that one. What you could do, is just terminate the subprocess, rather than try to send it a signal to shutdown:
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()
This is not as graceful as sending something through the queue (and doesn't allow for any additional clean-up in the sub-process, assuming you want it), but doesn't throw any exceptions.