Animating a 2D random walk, Python

Viewed 1446

I am trying to animate a random walk in 2 dimensions. I've been able to do this using turtle, but I want to learn this animation package. When I run the following code, I get a blank plane and I'm not sure why. Any suggestion is greatly appreciated!

import numpy as np
import matplotlib.pyplot as plt 
from matplotlib import animation
from matplotlib.animation import FuncAnimation
import random

x = 0
y = 0

x_data=[]
y_data=[]

fig, ax = plt.subplots()
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
line, = ax.plot(0,0)

def init():
    line.set_data([],[])
    return line,

def move_random(s,t):
    direction = random.randint(1,4)

    if direction == 1:
        s += 1
    elif direction == 2:
        t += 1
    elif direction == 3:
        s+= -1
    elif direction == 4:
        t+= -1

def animate_rw(i):
    move_random(x,y)

    x_data.append(x)
    y_data.append(y)

    line.set_xdata(x_data)
    line.set_ydata(y_data)
    return line,

anim = animation.FuncAnimation(fig, animate_rw, init_func = init, frames = 200, interval = 10)
plt.show()
2 Answers

You have passed frames as single integer. It should be numpy array of numbers. every of them is one pace. Another thing i see in your code is usage of i. You didn't pass it to your movement function. Already it's up to you. Another important thing is very weird, is x and y what is it in first time? You didn't return any value from move_random() to update them.

So one of the solution is change your code to be compatible with FuncAnimation() according to:

def move_random(s, t):
    direction = random.randint(1, 4)
    if direction == 1:
        s += 1
    elif direction == 2:
        t += 1
    elif direction == 3:
        s += -1
    elif direction == 4:
        t += -1
    # This line has added to this function
    return s, t


def animate_rw(i):
    # Attention to these
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    x, y = move_random(x, y)

    x_data.append(x)
    y_data.append(y)

    line.set_xdata(x_data)
    line.set_ydata(y_data)
    return line,

anim = FuncAnimation(fig, animate_rw, init_func=init, frames=200,    interval=10)

Alright so I've figured it out with the help of mece1390's comment about "frames," and also realizing that the variables x and y were not being "seen" inside of the animate function. I found I had to declare them as global inside the function:

x = 0
y = 0

x_data=[]
y_data=[]

def animate_rw(i):
    global x # kept getting a "local variable referenced before assignment error
    global y
# No need for the move_random function
    direction = random.randint(1, 4)
    if direction == 1:
        x += 1
    elif direction == 2:
        y += 1
    elif direction == 3:
        x += -1
    elif direction == 4:
        y += -1

    x_data.append(x)
    y_data.append(y)

    line.set_xdata(x_data)
    line.set_ydata(y_data)

    return line,
# Did not write in anything for frames, since it defaults to passing itertools.count
anim = FuncAnimation(fig, animate_rw, interval=600)
plt.show()
Related