I'm plotting some points moving in a 2D space and I want to add circles around them. I have all the x,y coordinates for the points around which the circles are supposed to be plotted, but I am unsure how to add this into the animate function.
Any help would be appreciated!
import matplotlib.pyplot as plt
from launcher import sol, T, dt
from matplotlib.animation import FuncAnimation, PillowWriter
from create import p, N, walls_x, walls_y
# convert sol.y to plottable array('s) using smart slicing
def sol_convert(sol):
#T = len(sol.t) # amount of time steps
x = sol.y[0::4,:] # there are 4 values p.p. (x,y,vx,vy)
y = sol.y[1::4,:]
vx = sol.y[2::4,:]
vy = sol.y[3::4,:]
return x, y, vx ,vy
r_x, r_y, v_x, v_y = sol_convert(sol)
fig, ax = plt.subplots()
xlimit, ylimit = [-1,26], [-1,16]
axis = plt.axes(xlim =(xlimit),
ylim =(ylimit))
for i in range(len(walls_x)):
plt.plot(walls_x[i],walls_y[i],'k',linestyle="solid")
ped, = axis.plot([], [], 'o')
# what will our line dataset contain?
def init():
ax.set_xlim(xlimit)
ax.set_ylim(ylimit)
ped.set_data([], [])
return ped,
# initializing empty values for x and y co-ordinates
xdata, ydata = [], []
# animation function
def animate(frame):
# t is a parameter which varies
# with the frame number
t = dt * frame
xdata = r_x[:,frame]
ydata = r_y[:,frame]
ped.set_data(xdata, ydata)
circles = plt.Circle((r_x[:,frame],r_y[:,frame]),2,color='r', fill=False)
ax.add_patch(circles)
return ped,
anim = FuncAnimation(fig, animate,
init_func = init,
frames = T,
interval = 20,
blit = True)
# saves the animation in our desktop
writergif = PillowWriter(fps=24)
anim.save('pedestrians.gif',writer=writergif)
I've tried adding code within the animate function, but I am very new to animation plotting and do not fully grasp what type of data can be given through this function.
Here is a minimal reproducible example:
# Minimal reproducable example
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter
# simulation variables
sim_time = 4 # total simulation time in [?] [is it in steps or in s]
dt = 0.5 # time step of the simulation in s
t = np.arange(0,sim_time,dt) # live running time of simulation
t_span = [t[0],t[-1]]
T = len(t) # amount of time steps for frames
fig, ax = plt.subplots()
xlimit, ylimit = [-1,26], [-1,16]
axis = plt.axes(xlim =(xlimit),
ylim =(ylimit))
points, = axis.plot([], [], 'o')
# what will our line dataset contain?
def init():
ax.set_xlim(xlimit)
ax.set_ylim(ylimit)
points.set_data([], [])
return points,
# initializing empty values for x and y co-ordinates
xdata, ydata = [], []
# animation function
def animate(frame):
# t is a parameter which varies
# with the frame number
t = dt * frame
xdata = np.random.rand(3)*10
ydata = np.random.rand(3)*10
points.set_data(xdata, ydata)
circles = plt.Circle((xdata,ydata),2,color='r', fill=False)
ax.add_patch(circles)
return points,
anim = FuncAnimation(fig, animate,
init_func = init,
frames = T,
interval = 20,
blit = True)
# saves the animation in our desktop
writergif = PillowWriter(fps=24)
anim.save('pedestrians.gif',writer=writergif)
CodePudding user response:
Instead of plt.circle
(which seems to me is not supported in Matplotlib v3.5.1), please use
An alternative method would store circles drawn at every frame and make them invisible before a new frame is drawn, along with using fig.canvas.draw()
:
circles = {}
ax.set_aspect("equal")
def animate(frame):
global circles
xdata = np.random.rand(3)*10
ydata = np.random.rand(3)*10
for i in circles.keys():
circles[i].set_visible(False)
for i in range(3):
circles[i] = Circle((xdata[i], ydata[i]), 2, color='r', fill=False)
ax.add_patch(circles[i])
points, = ax.plot(xdata, ydata, 'o', color='b')
fig.canvas.draw()
return points,