matplotlib FuncAnimation清除每个重复循环的图

时间:2017-11-09 01:49:26

标签: animation matplotlib polar-coordinates

下面的代码有效,但我认为每个重复周期都会过度绘制原始点。我希望它从原点,每个重复周期开始,带有清晰的图。在修复此问题的许多方法中,我尝试在init和update函数中插入ax.clear();没有效果。我在代码中留下了我认为会重置ln,艺术家有空集;再次,这不是我要找的解决方案。我希望得到一些指导,说明在这个玩具示例中重新启动每个循环的正确方法是什么,以便在应用于我更复杂的问题时,我不会产生累积惩罚。如果传递数组,这在刷新方面工作正常...感谢您的帮助。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, writers
#from basic_units import radians
# # Set up formatting for the movie files
# Writer = writers['ffmpeg']
# writer = Writer(fps=20, metadata=dict(artist='Llew'), bitrate=1800)

#Polar stuff
fig = plt.figure(figsize=(10,8))
ax = plt.subplot(111,polar=True)
ax.set_title("A line plot on a polar axis", va='bottom')
ax.set_rticks([0.5, 1, 1.5, 2])  # fewer radial ticks
ax.set_facecolor(plt.cm.gray(.95))
ax.grid(True)
xT=plt.xticks()[0]
xL=['0',r'$\frac{\pi}{4}$',r'$\frac{\pi}{2}$',r'$\frac{3\pi}{4}$',\
    r'$\pi$',r'$\frac{5\pi}{4}$',r'$\frac{3\pi}{2}$',r'$\frac{7\pi}{4}$']
plt.xticks(xT, xL)
r = []
theta = []
# Animation requirements.
ln, = plt.plot([], [], 'r:',
                    markersize=1.5,
                    alpha=1,
                    animated=True)

def init():
    ax.set_xlim(0, 2)
    ax.set_ylim(0, 2)
    return ln,

def update(frame):
    r.append(frame)
    theta.append(5*np.pi*frame)
    ln.set_data(theta, r)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0,2,400),
                    init_func=init, interval=10, blit=True,repeat=True)

plt.show()

我尝试使用这种稍微粗略的方法来重置列表(以及使用数组),这种方法擦除了列表,但没有重新启动循环。

def update(frame,r,theta):
    r.append(frame)
    theta.append(5*np.pi*frame)
    if len(r)>=400:
        r = [0]
        theta=[0]
    ln.set_data(theta, r)
    return ln,

相比之下,这确实有效......

for i in range(25):
    r.append(i)
    print('len(r)',len(r), r)
    if len(r) >=10:
        r = []
        print('if r>=10:',r)
    print('Post conditional clause r',len(r),r)

这导致我尝试以下操作,注意在update()内部传递内部(r,theta)需要将其声明为全局变量。使用以下代码,该图现在重置每个周期而不是过度绘图。我的感觉是,围绕一个简单的程序这是一个相当长的路 - 任何改进都是感激的。

#This solution also works
def update(frame):
        r.append(frame)
        theta.append(5*np.pi*frame)
        if len(r)>=400:
            global r
            r = []
            global theta
            theta=[]
        ln.set_data(theta, r)
        return ln,

1 个答案:

答案 0 :(得分:3)

如果我理解你的代码和你的问题,你想在动画的每一帧只显示一个点,这是正确的吗?

如果是这样,您的问题只是您每个新点附加到函数update()中的所有先前点。相反,只需更新数据坐标,如下所示:

def update(frame):
    r = frame
    theta = 2*np.pi*frame
    ln.set_data(theta, r)
    return ln,

enter image description here

编辑让我们看看这次是否正确。

您可以选择仅显示最后N点:

N=10
def update(frame):
    r.append(frame)
    theta.append(2*np.pi*frame)
    ln.set_data(theta[-N:], r[-N:])
    return ln,

enter image description here

或者您可以将N点附加到数组,然后重置为空数组。我想这可能就是你想要做的。在这里,你必须要小心。如果只是执行r = [],那么您可以更改哪个对象r引用,并且会中断动画。您需要做的是使用语法r[:] = []更改数组的内容

def update(frame):
    r_ = frame
    theta_ = 2*np.pi*frame
    if len(r)>N:
        r[:] = [r_]
        theta[:] = [theta_]
    else:    
        r.append(r_)
        theta.append(theta_)
    ln.set_data(theta, r)
    return ln,

enter image description here