Matplotlib圆形绘制和动画,如何在动画中移除旧的圆形?

4

我正在尝试使用Matplotlib的圆形和动画来模拟从选定数据点发出的圆形冲击波的动画。但是我无法找到一种方法在每个新帧中删除旧的圆。因此,随着半径的增加,我得到了越来越多的圆在画布上绘制 - 就像这样:

enter image description here

有关在matplotlib图中制作循环冲击波的任何建议?

我目前拥有的代码是:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

testData = np.random.rand(100,2)-[0.5, 0.5]

fig, ax = plt.subplots()
def init():
    fig.clf()
    sctPlot, = ax.plot(testData[:,0], testData[:,1], ".")

# i is the radius
def animate(i):
    init()
    q = 20 #initial index for the starting position
    pos = testData[q,:]
    circle1=plt.Circle(pos,i,color='r',fill=False, clip_on = False)
    fig.gca().add_artist(circle1)

def init():
    sctPlot, = ax.plot(testData[:,0], testData[:,1], ".")
    return sctPlot,

ani = animation.FuncAnimation(fig, animate, np.arange(0.4, 2, 0.1), init_func=init,
    interval=25, blit=False)
plt.show()
2个回答

5

我认为你可以每次使用set_radius来改变圆的大小:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


testData = np.random.rand(100,2)-[0.5, 0.5]

fig, ax = plt.subplots()
circle1=plt.Circle(testData[20,:],0,color='r',fill=False, clip_on = False)
ax.add_artist(circle1)
# i is the radius
def animate(i):
    #init()
    #you don't want to redraw the same dots over and over again, do you?
    circle1.set_radius(i)


def init():
    sctPlot, = ax.plot(testData[:,0], testData[:,1], ".")
    return sctPlot,

ani = animation.FuncAnimation(fig, animate, np.arange(0.4, 2, 0.1), init_func=init,
    interval=25, blit=False)
plt.show()

因此,您不需要在每个回合中删除并重新绘制贴片,我认为这可能更有效率。


谢谢...set_radius正是我所需要的。非常感谢。 - J_yang
嗨,又见面了。新代码运行良好,但在IPython笔记本上无法运行。它似乎会导致内核崩溃。我使用了“%pylab tk”来弹出plt窗口。你认为这与此有关吗? - J_yang
可能是TK问题吗?如果您不在IPython笔记本中,它可以工作吗?我正在使用OSX后端,完全没有遇到这个问题。 - CT Zhu
是的,在其他地方它可以工作,但在笔记本电脑上不行。你有什么建议?我已经将其更改为%pylab osx。但这不会导致弹出窗口。动画在笔记本电脑上无法在原地(或内联?)工作。 - J_yang
不知道 :(. 我在OSX后端上,弹出窗口可以工作。我通过%matplotlib进行了检查,并且确实返回了“使用matplotlib后端:MacOSX”。 - CT Zhu

2
将以下代码添加到您的animate函数中:
for obj in ax.findobj(match = type(plt.Circle(1, 1))):
  obj.remove()

ax.findobj(match = type(plt.Circle(1, 1))) 查找轴上的所有圆形补丁,您可以在绘制新圆之前将它们删除。我使用 plt.Circle() 创建了一个圆形对象进行匹配 - 您传递的参数实际上并不重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接