无法在 python matplotlib 中对同一补丁的克隆进行动画处理

Cannot animate clones of the same patch in python matplotlib

我目前正在尝试进行模拟,其中多个粒子代理(蓝点)试图跟随敌人粒子(红点)。我已经设法让我的模拟有一个蓝点跟随红点,但我无法在模拟中生成多个版本的蓝点(也试图让它出现在随机初始位置)并为所有蓝点制作动画跟随红点。

关于如何解决这个问题有什么想法吗?

尝试制作蓝色粒子克隆的动画:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from matplotlib.collections import PatchCollection
from matplotlib import cm

import random

fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)

ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')

p = None

def init():
    enemy.center = (5, 5)

    agent.center = (random.randint(1, 100), random.randint(1, 100))
    ax.add_patch(agent)

    for x in range(0,5):
        agent_clone = plt.Circle((10, -10), 0.75, fc='b')
        agent_clone.center = (random.randint(1, 100), random.randint(1, 100))
        patches_ac.append(agent_clone)


    p = PatchCollection(patches_ac, cmap=cm.prism, alpha=0.4)
    ax.add_collection(p)

    ax.add_patch(enemy)

    return []

def initalizePosition(agent,enemy):
    x_a, y_a = agent.center
    x_e, y_e = enemy.center

    x_a += 50
    y_a += 50

    agent.center = (x_a, y_a)
    enemy.center = (x_e, y_e)
    return agent    


def animationManage(i,agent,enemy):
    animateCos(i,enemy)
    #animateCirc(i,enemy)

    #animateLine(i,agent)
    followTarget(i,agent,enemy)

    return []

def followTarget(i, patch, enemy_patch):
    x, y = patch.center


    # Calculating velocity
    # v(t+1) = wv(t) + rand_1()c_1(p(t)  - x(t)) + rand_2()c_2(g(t) - x(t))
    v_x, v_y = velocity_calc(patch, enemy_patch)

    # Implementing:
    # x(t+1) = x(t) + v(t + 1)

    # x position
    x += v_x

    # y position
    y += v_y

    patch.center = (x, y)
    return patch,


def inertia_calc():
    return 0



def top_speed_regulate(curr_speed):
    top_speed = 0.5

    if curr_speed > top_speed:
        return top_speed
    elif curr_speed < -top_speed:
        return -top_speed
    else:
        return curr_speed

def velocity_calc(agent_patch, enemy_patch):

    x, y = agent_patch.center
    x_e, y_e = enemy_patch.center


    pos_vect = np.array([x,y], dtype='f')





    velo_vect = np.array([0.0,0.0], dtype='f')

    velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
    velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )



    return velo_vect[0], velo_vect[1]


def animateLine(i, patch):
    x, y = patch.center

    x += 0.25
    y += 0.25
    patch.center = (x, y)
    return patch,


def animateCos(i, patch):
    x, y = patch.center

    x += 0.1
    #x += 0.4

    y = 50 + 30 * np.cos(np.radians(i))
    #y = 50 + 10 * np.cos(np.radians(i))
    patch.center = (x, y)
    return patch,


def animateCirc(i, patch):
    # It seems that i represents time step
    x, y = patch.center
    # 1st constant = position and 2nd constant = trajectory
    x = 50 + 30 * np.sin(np.radians(i))
    y = 50 + 30 * np.cos(np.radians(i))
    patch.center = (x, y)
    return patch,




anim = animation.FuncAnimation(fig, animationManage,
                               init_func=init,
                               frames=1000,
                               fargs=(agent,enemy,),
                               interval=1,
                               blit=True,
                               repeat=True)


plt.show()

只有一个蓝色粒子的代码的工作版本:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

import random

fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)

ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')



def init():
    enemy.center = (5, 5)

    agent.center = (random.randint(1, 100), random.randint(1, 100))
    ax.add_patch(agent)

    ax.add_patch(enemy)

    return []

def initalizePosition(agent,enemy):
    x_a, y_a = agent.center
    x_e, y_e = enemy.center

    x_a += 50
    y_a += 50

    agent.center = (x_a, y_a)
    enemy.center = (x_e, y_e)
    return agent    


def animationManage(i,agent,enemy):
    animateCos(i,enemy)
    #animateCirc(i,enemy)

    #animateLine(i,agent)
    followTarget(i,agent,enemy)

    return []

def followTarget(i, patch, enemy_patch):
    x, y = patch.center


    # Calculating velocity
    # v(t+1) = wv(t) + rand_1()c_1(p(t)  - x(t)) + rand_2()c_2(g(t) - x(t))
    v_x, v_y = velocity_calc(patch, enemy_patch)

    # Implementing:
    # x(t+1) = x(t) + v(t + 1)

    # x position
    x += v_x

    # y position
    y += v_y

    patch.center = (x, y)
    return patch,


def inertia_calc():
    return 0



def top_speed_regulate(curr_speed):
    top_speed = 0.5

    if curr_speed > top_speed:
        return top_speed
    elif curr_speed < -top_speed:
        return -top_speed
    else:
        return curr_speed

def velocity_calc(agent_patch, enemy_patch):

    x, y = agent_patch.center
    x_e, y_e = enemy_patch.center


    pos_vect = np.array([x,y], dtype='f')





    velo_vect = np.array([0.0,0.0], dtype='f')
    '''
    velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )* random.random() 
    velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )* random.random()
    '''

    velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
    velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )



    return velo_vect[0], velo_vect[1]


def animateLine(i, patch):
    x, y = patch.center

    x += 0.25
    y += 0.25
    patch.center = (x, y)
    return patch,


def animateCos(i, patch):
    x, y = patch.center

    x += 0.1
    #x += 0.4

    y = 50 + 30 * np.cos(np.radians(i))
    #y = 50 + 10 * np.cos(np.radians(i))
    patch.center = (x, y)
    return patch,


def animateCirc(i, patch):
    # It seems that i represents time step
    x, y = patch.center
    # 1st constant = position and 2nd constant = trajectory
    x = 50 + 30 * np.sin(np.radians(i))
    y = 50 + 30 * np.cos(np.radians(i))
    patch.center = (x, y)
    return patch,




anim = animation.FuncAnimation(fig, animationManage,
                               init_func=init,
                               frames=1000,
                               fargs=(agent,enemy,),
                               interval=1,
                               blit=True,
                               repeat=True)


plt.show()
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

import random

fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(5, 4.5)

ax = plt.axes(xlim=(0, 100), ylim=(0, 100))
enemy = plt.Circle((10, -10), 0.75, fc='r')
agent = plt.Circle((10, -10), 0.75, fc='b')
patches_ac = []
ax.add_patch(agent)

for x in range(0, 5):
    agent_clone = plt.Circle((10, -10), 0.75, fc='b')
    agent_clone.center = (random.randint(1, 100), random.randint(1, 100))
    patches_ac.append(agent_clone)
    ax.add_patch(agent_clone)

ax.add_patch(enemy)


def init():
    enemy.center = (5, 5)

    agent.center = (random.randint(1, 100), random.randint(1, 100))
    for ac in patches_ac:
        ac.center = (random.randint(1, 100), random.randint(1, 100))
    return []


def animationManage(i):
    animateCos(i, enemy)
    followTarget(i, agent, enemy)
    for ac in patches_ac:
        followTarget(i, ac, enemy)

    return []

def followTarget(i, patch, enemy_patch):
    x, y = patch.center
    v_x, v_y = velocity_calc(patch, enemy_patch)

    # x position
    x += v_x

    # y position
    y += v_y

    patch.center = (x, y)
    return patches_ac


def top_speed_regulate(curr_speed):
    top_speed = 0.5

    if curr_speed > top_speed:
        return top_speed
    elif curr_speed < -top_speed:
        return -top_speed
    else:
        return curr_speed


def velocity_calc(agent_patch, enemy_patch):

    x, y = agent_patch.center
    x_e, y_e = enemy_patch.center

    velo_vect = np.array([0.0, 0.0], dtype='f')

    velo_vect[0] = top_speed_regulate( (x_e - x)* 0.05 )
    velo_vect[1] = top_speed_regulate( (y_e - y)* 0.05 )

    return velo_vect[0], velo_vect[1]


def animateCos(i, patch):
    x, y = patch.center
    x += 0.1

    y = 50 + 30 * np.cos(np.radians(i))
    patch.center = (x, y)
    return patch,


anim = animation.FuncAnimation(fig, animationManage,
                               init_func=init,
                               frames=1000,
                               interval=1,
                               blit=True,
                               repeat=True)


plt.show()