Reputation: 143
I am making an animation in matplotlib, where dots are moving in a certain direction. I would like them to disappear, when they reach a given value.
In the following code, the dots are moving in a U shape and stop at the end.
I would like the dots to disappear, when they stop, at x= 7-9
, y=7
:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
import random
n_particles = 40
b_particles=5
box_width = 10
n_steps = 5000
dt = 0.001
fig, ax = plt.subplots()
ax.set_xlim(0, 20)
ax.set_ylim(0, 20)
# -------
def get_initial_coordinates():
x=[random.uniform(2,3) for i in range(n_particles)]
y=[random.uniform(2,7) for i in range(n_particles)]
return x,y
def get_initial_velocities():
directions=[np.array([0,1]),np.array([1,0]),np.array([-1,0]),np.array([0,-1])]
direction=random.choice(directions)
d1 = []
for i in range(n_particles):
d1.append(random.choice(directions))
d1 = np.array(d1)
xv=[ 0 for i in range(n_particles)]
yv=[ -20 for i in range(n_particles)]
return xv, yv
throughwall = []
for i in range(n_particles):
throughwall.append(random.random() * 100)
def take_step(x,y,xv,yv):
for i in range(n_particles):
x[i] +=xv[i]*dt
y[i] +=yv[i]*dt
if y[i] <= random.uniform(-1,3):
xv[i] = 20
yv[i]=0
if x[i] >=random.uniform(7,10):
xv[i]=0
yv[i]= 20
if y[i] >=7 and 7<x[i]<9:
xv[i]=0
yv[i]=0
return x,y,xv,yv
x,y = get_initial_coordinates()
xv,yv= get_initial_velocities()
for i in range(n_steps):
x,y,xv,yv= take_step(x,y,xv,yv)
#---------------------
fig = plt.figure()
ax = plt.axes(xlim=(0, 10), ylim=(0, 10))
ax.set_aspect('equal')
e, = ax.plot([x[i] for i in range(n_particles)],
[y[i] for i in range(n_particles)], 'ro')
x,y= get_initial_coordinates()
xv,yv= get_initial_velocities()
import matplotlib.patches as patches
ax.add_patch(
patches.Rectangle(
(3, 3),4,4,edgecolor = 'blue', fill=False) )
ax.add_patch(
patches.Rectangle(
(2, 2),6,5,edgecolor = 'blue',fill=False) )
def animate(i):
take_step(x,y,xv,yv)
e.set_data([x[i]for i in range(n_particles)],
[y[i] for i in range(n_particles)])
return e,
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)
plt.show()
Upvotes: 1
Views: 492
Reputation: 80459
At the moment the particle reaches the end, one could set its position far outside the view. The code below sets the y
at 1000. As the view limits (xlim
and ylim
) aren't changed, the dot will be invisible.
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import animation
import numpy as np
import random
n_particles = 40
b_particles = 5
box_width = 10
dt = 0.001
fig, ax = plt.subplots()
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_aspect('equal')
def get_initial_coordinates():
x = np.random.uniform(2, 3, n_particles)
y = np.random.uniform(2, 7, n_particles)
return x, y
def get_initial_velocities():
xv = np.zeros(n_particles)
yv = np.zeros(n_particles) - 20
return xv, yv
def take_step(x, y, xv, yv):
for i in range(n_particles):
x[i] += xv[i] * dt
y[i] += yv[i] * dt
if y[i] <= random.uniform(-1, 3):
xv[i] = 20
yv[i] = 0
if x[i] >= random.uniform(7, 10):
xv[i] = 0
yv[i] = 20
if y[i] >= 7 and 7 < x[i] < 9:
xv[i] = 0
yv[i] = 0
if y[i] >= 7 and x[i] >= 7:
y[i] = 10000
return x, y, xv, yv
x, y = get_initial_coordinates()
xv, yv = get_initial_velocities()
e, = ax.plot(x, y, 'ro')
ax.add_patch(
patches.Rectangle(
(3, 3), 4, 4, edgecolor='blue', fill=False))
ax.add_patch(
patches.Rectangle(
(2, 2), 6, 5, edgecolor='blue', fill=False))
def animate(i):
take_step(x, y, xv, yv)
e.set_data(x, y)
return e,
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)
plt.show()
An alternative could be to draw a reservoir where the particles will stop. Making the reservoir white, and setting its zorder
higher than the dots (default the dots get zorder
2) will make the dots hidden. For the reservoir not to hide the border of the U shape, the rectangles of the U shape can get a still higher zorder
.
The code below lets the particles stop near y == 7.5
to make sure they arrive at the center of the reservoir.
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import animation
import numpy as np
import random
n_particles = 40
b_particles = 5
box_width = 10
dt = 0.001
fig, ax = plt.subplots()
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_aspect('equal')
def get_initial_coordinates():
x = np.random.uniform(2, 3, n_particles)
y = np.random.uniform(2, 7, n_particles)
return x, y
def get_initial_velocities():
xv = np.zeros(n_particles)
yv = np.zeros(n_particles) - 20
return xv, yv
def take_step(x, y, xv, yv):
for i in range(n_particles):
x[i] += xv[i] * dt
y[i] += yv[i] * dt
if y[i] <= random.uniform(-1, 3):
xv[i] = 20
yv[i] = 0
if x[i] >= random.uniform(7, 10):
xv[i] = 0
yv[i] = 20
if y[i] >= 7.5 and 7 < x[i] < 9:
xv[i] = 0
yv[i] = 0
return x, y, xv, yv
x, y = get_initial_coordinates()
xv, yv = get_initial_velocities()
e, = ax.plot(x, y, 'ro')
ax.add_patch(
patches.Rectangle(
(3, 3), 4, 4, edgecolor='blue', fill=False, zorder=4))
ax.add_patch(
patches.Rectangle(
(2, 2), 6, 5, edgecolor='blue', fill=False, zorder=4))
# draw the reservoir, white makes it invisible, change its color
# to `facecolor='gold', alpha=0.5` to see what's happening
ax.add_patch(
patches.Rectangle(
(6, 7), 3, 1, edgecolor='none', facecolor='white', zorder=3))
def animate(i):
take_step(x, y, xv, yv)
e.set_data(x, y)
return e,
anim = animation.FuncAnimation(fig, animate, frames=200, interval=20)
plt.show()
Upvotes: 1