Matplotlib动画:使用blit时,第一帧仍保留在画布中

时间:2014-01-29 18:26:30

标签: python matplotlib

我正在尝试使用Matplotlib动画库绘制两个旋转椭圆,我设法让它工作(或多或少)。问题是正在渲染的第一帧不会更新,所以当我在画布中有两个旋转椭圆时,我也有原始位置/方向的椭圆。看看我简单的代码:

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

知道怎么解决这个问题吗?我当然可以关闭blit,但这会让它非常慢,所以这不是一个真正的选择。

编辑:最终(工作)代码

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

2 个答案:

答案 0 :(得分:3)

试试这个:

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

尝试这种其他方法(不是我只使用一个椭圆进行测试,它也可以在这里渲染):

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

答案 1 :(得分:3)

建议的答案看起来像是一个黑客。你隐藏了一帧的补丁,然后将其显示在下一帧,没有押韵或理由。此外,我注意到每当您调整绘图大小时都会调用init函数,这会在使用建议的解决方案调整大小后使椭圆不可见。

我认为正确的方法是在animated=True对象上设置Ellipse。请参阅matplotlib animation documentation。这里有一些适合我的代码:

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, animated=True)
e2 = Ellipse(xy=(0.8, 0.8), width=0.5, height=0.2, angle=100, animated=True)
ax.add_patch(e1)
ax.add_patch(e2)

def init():
    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()