下面是一个完全有效的代码,该动画为具有周期性边界的单车道动画。现在,我想为两个甚至更多车道设置动画。我有一个工作代码,其中位置矢量现在是一个矩阵,每列代表一个车道。由此,我可以创建另一个theta矢量,希望将其显示在动画的第一个theta之外(通过将半径设置得更大一些)。我试图将矩阵(theta和r)放入ax.scatter(theta,r,c = color),但这不起作用。有人对如何解决这个问题有建议吗?除了可以使用matplotlib的动画外,我还可以使用其他方法,但是由于它可以很好地解决单车道问题,因此对我来说最简单。

总结一下。如何同时为两个或更多矢量设置动画?例如,如果我有r1,r2和theta1,theta2,并希望每次都“绘制”它们,而不是像代码中那样仅绘制r和theta。

非常感谢您的帮助。

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

roadlength = 50
numcars = 10
numframes = 1000  #Time
v_max = 5
p = 0.5

positions = np.zeros(numcars)
velocities = np.zeros(numcars)
theta = np.zeros(numcars)
color = np.linspace(0,numcars-1,numcars)

#Initiate r so roadlength = circumference of one lap
r = []
for i in range(numcars):
    r.append(roadlength/(2*np.pi))

#Initiate positions so the cars are spread out over the road
for i in range(1,numcars):
    positions[i] = positions[i-1] + (roadlength/numcars)

#Create figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.axis('off')

#Update positions, animate function runs framenr times
def animate(framenr):
    positions_tmp = np.array(positions, copy=True)

    #Update position and velocity for each car
    for i in range(numcars):

        #Increase velocity if below max
        if velocities[i] < v_max:
                velocities[i] += 1
        #Decrease velocity if car in front is close
        d = positions_tmp[(i+1)%numcars] - positions_tmp[i]
        if d <= 0:
            d += roadlength
        if velocities[i] >= d:
            velocities[i] = d-1
        #Decrease velocity randomly
        if velocities[i] > 0:
            if rnd() < p:
                velocities[i] -= 1

        positions[i] = positions_tmp[i] + velocities[i]
        theta[i] = positions[i]*2*np.pi/roadlength

    return ax.scatter(theta, r, c=color),

# Call the animator, blit=True means only re-draw parts that have changed
anim = animation.FuncAnimation(fig, animate, frames=numframes, interval=100, blit=True, repeat=False)
plt.show()

最佳答案

FuncAnimation()期望animate()函数返回在每个帧处已更新的艺术家数组。如果您需要为多个“图形”(或艺术家等)制作动画,只需存储每个绘图的结果,然后返回所有变量的列表

另外,您的代码在ax.scatter()函数中反复调用animate,这会导致每次绘制新点,并且绘制框架所花费的时间会随着时间增加。我不知道那是否真的是您真正想做的。动画的最佳实践是在动画开始之前创建艺术家,然后在animate()函数中更新其属性,而不是创建新的。

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

roadlength = 50
numcars = 10
numframes = 1000  #Time
v_max = 5
p = 0.5

positions = np.zeros(numcars)
velocities = np.zeros(numcars)
theta = np.zeros(numcars)
color = np.linspace(0,numcars-1,numcars)

#Initiate r so roadlength = circumference of one lap
r = roadlength/(2*np.pi)

#Initiate positions so the cars are spread out over the road
for i in range(1,numcars):
    positions[i] = positions[i-1] + (roadlength/numcars)

#Create figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.axis('off')

plot1 = ax.scatter(theta, [r]*numcars, c=color)
plot2 = ax.scatter(theta, [r+1]*numcars, c=color)

ax.set_ylim(0,r+2)

#Update positions, animate function runs framenr times
def animate(framenr):
    positions_tmp = np.array(positions, copy=True)

    #Update position and velocity for each car
    for i in range(numcars):

        #Increase velocity if below max
        if velocities[i] < v_max:
                velocities[i] += 1
        #Decrease velocity if car in front is close
        d = positions_tmp[(i+1)%numcars] - positions_tmp[i]
        if d <= 0:
            d += roadlength
        if velocities[i] >= d:
            velocities[i] = d-1
        #Decrease velocity randomly
        if velocities[i] > 0:
            if rnd() < p:
                velocities[i] -= 1

        positions[i] = positions_tmp[i] + velocities[i]
        theta[i] = positions[i]*2*np.pi/roadlength

    plot1.set_offsets(np.c_[theta, [r]*numcars])
    plot2.set_offsets(np.c_[theta, [r+1]*numcars])

    return [plot1, plot2]

# Call the animator, blit=True means only re-draw parts that have changed
anim = animation.FuncAnimation(fig, animate, frames=numframes, interval=100, blit=True, repeat=True)
plt.show()


python - 使用matplotlib.animation.FuncAnimation对具有周期性边界的多车道高速公路进行动画处理-LMLPHP

07-25 22:19
查看更多