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