Cannot animate clones of the same patch in python matplotlib

余生颓废 提交于 2020-01-03 04:15:07

问题


I am currently trying to make a simulation in which multiple particle agents (blue dots) try to follow the enemy particle (red dot). I have managed to get my simulation to have one blue dot follow the red dot, but I am having trouble producing multiple version of the blue dots (also trying ot get it to appear at random initial locations) in the simulation and animating all of them to follow the red dot.

Any ideas on how to fix this?

Attempt to animate clones of blue particles:

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()

Working version of the code with just one blue particle:

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()

回答1:


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()


来源:https://stackoverflow.com/questions/38446295/cannot-animate-clones-of-the-same-patch-in-python-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!