Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
530 views
in Technique[技术] by (71.8m points)

python - Matplotlib animation: first frame remains in canvas when using blit

I'm trying to plot two rotating ellipses using the Matplotlib animation library, and I managed to get it working (more or less). The problem is that the first frame that is being rendered does not update, so while I got two rotating ellipses in my canvas, I also have the ellipses in their original position/orientation. Check out my simple piece of code:

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from matplotlib import animation

fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
e1 = Ellipse(xy=(0.5, 0.5), width=0.5, height=0.2, angle=60)
e2 = Ellipse(xy=(0.8, 0.8), width=0.5, height=0.2, angle=100)

def init():
    ax.add_patch(e1)
    ax.add_patch(e2)
    return [e1,e2]

def animate(i):
    e1.angle = e1.angle + 0.5
    e2.angle = e2.angle + 0.5
    return [e1,e2]

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1, blit=True)
plt.show()

Any idea how to fix this? I could of course turn off blit, but that makes it horribly slow, so that's not really an option.

EDIT: Final (working) Code

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from matplotlib import animation

fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
e1 = Ellipse(xy=(0.5, 0.5), width=0.5, height=0.2, angle=60)
e2 = Ellipse(xy=(0.8, 0.8), width=0.5, height=0.2, angle=100)
ax.add_patch(e1)
ax.add_patch(e2)

def init():
    e1.set_visible(False)
    e2.set_visible(False)
    return [e1,e2]

def animate(i):
    if i == 1:
        e1.set_visible(True)
        e2.set_visible(True)
    e1.angle = e1.angle + 0.5
    e2.angle = e2.angle + 0.5
    return [e1,e2]

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1, blit=True)
plt.show()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this:

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from matplotlib import animation

fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
e1 = Ellipse(xy=(0.5, 0.5), width=0.5, height=0.2, angle=60)
e2 = Ellipse(xy=(0.8, 0.8), width=0.5, height=0.2, angle=100)


def init():
    return [ax]

def animate(i):
    if i==0:
        ax.add_patch(e1)
        ax.add_patch(e2)    
    e1.angle = e1.angle + 0.5
    e2.angle = e2.angle + 0.5
    return [e1,e2]

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1, blit=True)
plt.show()

Screen-shot showing the correct behavior

Try this other approach (not I've used only one ellipse just for testing, it also renders fine here):

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from matplotlib import animation

fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
e1 = Ellipse(xy=(0.5, 0.5), width=0.5, height=0.2, angle=60)
ax.add_patch(e1)

def init():
    e1.set_visible(False)
    return e1,

def animate(i):
    if i==0:
        e1.set_visible(True)
    e1.angle = e1.angle + 0.5
    return e1,

anim = animation.FuncAnimation(fig, animate, init_func=init, interval=1, blit=True)
plt.show()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...