matplotlib FuncAnimation clear plot 每个重复循环

matplotlib FuncAnimation clear plot each repeat cycle

下面的代码有效,但我认为在每个重复循环中都过度绘制了原始点。我希望它从原点开始,每个重复周期,有一个清晰的情节。在许多解决此问题的方法中,我尝试在 init 和 update 函数中插入 ax.clear() ;没有效果。我在代码中留下了我认为会将 ln, artist 重置为空集的内容;同样,这不是我正在寻找的解决方案。我希望在此玩具示例中提供有关重新启动每个周期的正确方法的一些指导,以便在应用于我的更复杂的问题时,我不会招致累积惩罚。如果传递数组,这在刷新方面效果很好...感谢您的帮助。

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,

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

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

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

编辑 让我们看看这次我是否做对了。

您可以选择只显示最后 N 个点,如下所示:

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

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

更改数组的 content
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,