Reputation: 11
i am using Python 2.7 (Anaconda) with matplotlib to get the animation of a square patch on a "desk" square patch -background-, so that the little square has to move along a required direction (north,south,est,west) for range=n positions(move=1). I'm using FuncAnimation for my first time, but as plot i only get the square plotted n times instead of have it moving/animated. Here is my code with sample direction "south":
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
from matplotlib import animation
import numpy as np
#__________________________________________________________________________PLOT
fig = plt.figure()
ax1 = fig.add_subplot(111,aspect='equal')
ax1.set_xlim((0,10))
ax1.set_ylim((0,10))
#________________________________________________FIGURES_VECTORS_INITIALIZATION
#DESK
desk=np.matrix([[1,1],[9,1],[9,9],[1,9]]) #desk vertices
#setting initialization - DESK
def initDesk():
ax1.add_patch(ptc.Polygon(desk, closed=True,
fill=False, hatch="/"))
#SQUARE
squVer=np.matrix([[4.5,6.5],[5.5,6.5],[5.5,7.5],[4.5,7.5]]) #square vertices
#_____________________________________________________DIRECTIONS_INITIALIZATION
move=1
null=0
#4DIRECTIONS
north=np.array(([+null,+move]))
south=np.array([+null,-move])
est=np.array([+move,+null])
west=np.array([-move,+null])
#_____________________________________________________________________ANIMATION
def animate(newPos):
iniSqu=np.matrix(squVer)
position=newPos
for step in range (0,4):
if step < 1: #starting point
newPos=iniSqu
else:
newPos=iniSqu+position
square=ptc.Polygon(newPos, closed=True,
facecolor="blue")
ax1.add_patch(square)
iniSqu=newPos
anim = animation.FuncAnimation(fig, animate(south),init_func=initDesk(),repeat=True)
plt.show()
Suggestions about what could fix the problem and get the patch animated instead of get plotted n times on the same figure?
Upvotes: 1
Views: 1019
Reputation: 339230
You misunderstood the way FuncAnimation
works. Its signature is
FuncAnimation(figure, func, frames, ...)
where func
is the function that gets repeatedly called and frames
is a number, list or array, or a generator.
The function func
is called for each time step with a new argument according to frames
. In your code above the function already does everything for each call, which is of course undesired. Instead it should do something different for every call.
Further, you should not call the function yourself, but only provide it to the FuncAnimaton
class, which will then call it.
So it's really FuncAnimation(figure, func, frames, ...)
and not FuncAnimation(figure, func(something), frames, ...)
To make the animation such that the square moves southwards four times, frames
would then be a list like frames = [south, south, south, south]
.
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
from matplotlib import animation
import numpy as np
fig = plt.figure()
ax1 = fig.add_subplot(111,aspect='equal')
ax1.set_xlim((0,10))
ax1.set_ylim((0,10))
desk=np.matrix([[1,1],[9,1],[9,9],[1,9]]) #desk vertices
#SQUARE
squVer=np.matrix([[4.5,6.5],[5.5,6.5],[5.5,7.5],[4.5,7.5]]) #square vertices
iniSqu=[squVer]
move=1
null=0
#4DIRECTIONS
north=np.array(([+null,+move]))
south=np.array([+null,-move])
est=np.array([+move,+null])
west=np.array([-move,+null])
deskpoly = [ptc.Polygon(desk, closed=True, fill=False, hatch="/")]
squarepoly = [ptc.Polygon(iniSqu[0], closed=True, facecolor="blue")]
def initDesk():
ax1.clear()
ax1.set_xlim((0,10))
ax1.set_ylim((0,10))
iniSqu[0] = squVer
ax1.add_patch(deskpoly[0])
ax1.add_patch(squarepoly[0])
def animate(direction):
iniSqu[0] = iniSqu[0] + direction
squarepoly[0].remove()
squarepoly[0] = ptc.Polygon(iniSqu[0], closed=True, facecolor="blue")
ax1.add_patch(squarepoly[0])
frames = (south, south, south, south)
anim = animation.FuncAnimation(fig, animate, frames=frames, init_func=initDesk,repeat=True)
plt.show()
Upvotes: 2