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:
我正在尝试使用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()
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.
你知道怎么解决这个问题吗?我当然可以关闭blit,但是这使得它非常慢,所以这不是一个选项。
Thanks!
谢谢!
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()
2 个解决方案
#1
3
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()
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()
#2
3
The proposed answer seems like a hack. You're hiding the patch for one frame, then showing it the next, for no rhyme or reason. Also, I noticed the init
function gets called whenever you resize the plot, which would then make the ellipse invisible after resizing with the proposed solution.
提议的答案似乎是一个黑客。你把补丁藏在一帧中,然后在另一帧中显示出来,没有任何韵或理由。此外,我注意到,每当您调整绘图的大小时,就会调用init函数,这将使椭圆在使用所建议的解决方案调整大小之后变得不可见。
I think the correct way to do this is to set animated=True
on the Ellipse
objects. See the matplotlib animation documentation. Here's some code that works for me:
我认为正确的方法是在椭圆对象上设置animation =True。参见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, 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()
#1
3
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()
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()
#2
3
The proposed answer seems like a hack. You're hiding the patch for one frame, then showing it the next, for no rhyme or reason. Also, I noticed the init
function gets called whenever you resize the plot, which would then make the ellipse invisible after resizing with the proposed solution.
提议的答案似乎是一个黑客。你把补丁藏在一帧中,然后在另一帧中显示出来,没有任何韵或理由。此外,我注意到,每当您调整绘图的大小时,就会调用init函数,这将使椭圆在使用所建议的解决方案调整大小之后变得不可见。
I think the correct way to do this is to set animated=True
on the Ellipse
objects. See the matplotlib animation documentation. Here's some code that works for me:
我认为正确的方法是在椭圆对象上设置animation =True。参见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, 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()