'Is there a way to iteratively add plots to Animation.FuncAnimation()?
I'm working on my master thesis right now and need to animate a high number of points moving. Those points will be representing predators and prey. The number of predators and preys should be changeable and probably around 500 each. For now i hard coded the animation function with 3 predators and 1 prey. is there a way to do it iteratively (e.g for 500 predators and 200 preys)?
EDIT: In google colab the animation is stretched is there a way to make it a proper square?
Thanks in advance!
My code so far (just have random movement for p&p so code is smaller):
import matplotlib
import random
import numpy as np
from matplotlib import pyplot
from matplotlib import animation
from matplotlib import rc
rc('animation', html='jshtml')
max_t=200 # max experiment time
num_pred = 3 # number of predators
num_prey = 1 # number of prey
pred_pos = np.zeros((2*num_pred, max_t)) # initializing x and y positions for pred based on time
prey_pos = np.zeros((2*num_prey, max_t)) # initializing x and y positions for prey based on time
# [pred1_x1, pred1_x2, pred1_x3,...
# pred1_y1, pred1_y2, pred1_y3,...
# pred2_x1, pred2_x2, pred2_x3,...
# pred2_y1, pred2_y2, pred2_y3,...]
for i in range(2*num_pred):
pred_pos[i][0] = pred_pos[i][0] + random.uniform(-1, 1)
for j in range(max_t-1):
pred_pos[i][j] = pred_pos[i][j-1] + random.uniform(-1, 1) # random movement
for i in range(2*num_prey):
prey_pos[i][0] = prey_pos[i][0] + random.uniform(-1, 1)
for j in range(max_t-1):
prey_pos[i][j] = prey_pos[i][j-1] + random.uniform(-1, 1)
#print(pred_pos)
#print(prey_pos)
fig=pyplot.figure()
ax = pyplot.axes(xlim=(-10, 10), ylim=(-10, 10))
pred_circle1=pyplot.Circle((pred_pos[0,0],pred_pos[1,0]),0.3,fc='b')
pred_circle2=pyplot.Circle((pred_pos[2,0],pred_pos[3,0]),0.3,fc='b')
pred_circle3=pyplot.Circle((pred_pos[4,0],pred_pos[5,0]),0.3,fc='b')
prey_circle1=pyplot.Circle((prey_pos[0,0],prey_pos[1,0]),0.3,fc='r')
def init():
pred_circle1.center=(pred_pos[0,0],pred_pos[1,0]) # pred_circle1.center=(x,y)
pred_circle2.center=(pred_pos[2,0],pred_pos[3,0])
pred_circle3.center=(pred_pos[4,0],pred_pos[5,0])
prey_circle1.center=(prey_pos[0,0],prey_pos[1,0])
ax.add_patch(pred_circle1)
ax.add_patch(pred_circle2)
ax.add_patch(pred_circle3)
ax.add_patch(prey_circle1)
return pred_circle1, pred_circle2, pred_circle3, prey_circle1,
def animate(i):
pred_circle1.center=(pred_pos[0,i],pred_pos[1,i])
pred_circle2.center=(pred_pos[2,i],pred_pos[3,i])
pred_circle3.center=(pred_pos[4,i],pred_pos[5,i])
prey_circle1.center=(prey_pos[0,i],prey_pos[1,i])
return pred_circle1, pred_circle2, pred_circle3, prey_circle1,
anim=animation.FuncAnimation(fig,animate, init_func=init,frames=max_t,blit=True)
anim
Solution 1:[1]
One way to achieve it is by knowing that your first add all the predators, then all the preys. So, ax.patches
contains an ordered list of patches, and you can loop over them to update their positions:
import matplotlib
import random
import numpy as np
from matplotlib import pyplot
from matplotlib import animation
max_t=200 # max experiment time
num_pred = 15 # number of predators
num_prey = 4 # number of prey
pred_pos = np.zeros((2*num_pred, max_t)) # initializing x and y positions for pred based on time
prey_pos = np.zeros((2*num_prey, max_t)) # initializing x and y positions for prey based on time
# [pred1_x1, pred1_x2, pred1_x3,...
# pred1_y1, pred1_y2, pred1_y3,...
# pred2_x1, pred2_x2, pred2_x3,...
# pred2_y1, pred2_y2, pred2_y3,...]
for i in range(2*num_pred):
pred_pos[i][0] = pred_pos[i][0] + random.uniform(-1, 1)
for j in range(max_t-1):
pred_pos[i][j] = pred_pos[i][j-1] + random.uniform(-1, 1) # random movement
for i in range(2*num_prey):
prey_pos[i][0] = prey_pos[i][0] + random.uniform(-1, 1)
for j in range(max_t-1):
prey_pos[i][j] = prey_pos[i][j-1] + random.uniform(-1, 1)
fig=pyplot.figure()
ax = pyplot.axes(xlim=(-10, 10), ylim=(-10, 10))
# add an arbitrary number of preys and predators
for i in range(num_pred):
p = pyplot.Circle((pred_pos[2 * i, 0], pred_pos[2 * i + 1, 0]),0.3,fc='b')
ax.add_patch(p)
for i in range(num_prey):
p = pyplot.Circle((prey_pos[2 * i, 0], prey_pos[2 * i + 1, 0]),0.3,fc='r')
ax.add_patch(p)
def animate(i):
# update positions
for k in range(num_pred):
ax.patches[k].center=(pred_pos[2*k,i],pred_pos[2*k+1,i])
for k in range(num_prey):
ax.patches[num_pred + k].center=(prey_pos[2*k,i],prey_pos[2*k+1,i])
anim=animation.FuncAnimation(fig,animate, frames=max_t)
pyplot.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Davide_sd |