Matplotlib 动画:在绘图中累积帧而不是覆盖?

Matplotlib animation: Accumulate frames in plot instead of overwriting?

我一直在尝试重新创建 this animation in matplotlib by roughly following the answer to this thread: (它是 PI 的 monte carlo 近似值)。

我想知道如何在我的绘图中累积帧,以便每个帧在先前绘制的帧之上添加额外的点,以便随着时间的推移这些点变得越来越密集。另外,我是否必须从根本上重写我的代码,因为 PI 的近似要求我携带每次迭代计数的蓝色和红色点数?

fig, ax = plt.subplots(figsize=(5,5))

plt.rcParams['animation.ffmpeg_path'] = r'C:\FFmpeg\bin\ffmpeg'

b_sc = ax.scatter([],[],s=1,c='b')
r_sc = ax.scatter([],[],s=1,c='r')


def init():

    ax.set_ylim(0,1)
    ax.set_xlim(0,1)

    return b_sc,r_sc


def update(frame):

    org = np.array([0,0])
    r, b = (0,0)

    np.random.seed(frame)

    dots = np.random.rand(100,2)
    blue = np.array([dot for dot in dots if np.linalg.norm(org-dot) <= 1])
    red = np.array([dot for dot in dots if np.linalg.norm(org-dot) > 1])

    dr, db = red.shape[0], blue.shape[0]

    r += dr
    b += db

    pi = b/(frame*(100))*4

    if db != 0:
        b_sc.set_offsets(blue)
    if dr != 0:
        r_sc.set_offsets(red)

#    ax.figure.canvas.draw()

    return b_sc,r_sc


FFwriter = animation.FFMpegWriter(fps=144)

ani = FuncAnimation(fig, update, frames=range(1,100), interval=1,
                    init_func=init, blit=True)

plt.show()

您实际上可以使用 extend 方法为该动画利用列表的可变性。

fig, ax = plt.subplots(figsize=(5,5))

# plt.rcParams['animation.ffmpeg_path'] = r'C:\FFmpeg\bin\ffmpeg'

b_sc = ax.scatter([],[],s=1,c='b')
r_sc = ax.scatter([],[],s=1,c='r')
txt = ax.text(.9, .1, '', backgroundcolor='w') # let's print pi on the animation!

# init empty lists
blue=[] 
red=[]

def init():

    ax.set_ylim(0,1)
    ax.set_xlim(0,1)

    return b_sc,r_sc


def update(frame):

    org = np.array([0,0])
    r, b = (0,0)

    np.random.seed(frame)

    dots = np.random.rand(100,2)

    # swap the numpy computation for a list extention
    blue.extend([dot for dot in dots if np.linalg.norm(org-dot) <= 1])
    red.extend([dot for dot in dots if np.linalg.norm(org-dot) > 1])

    # don't forget to change this to `len` since `shape` no longer applies
    dr, db = len(red), len(blue)

    r += dr
    b += db

    pi = b/(frame*(100))*4
    txt.set_text('{:.3f}'.format(pi))

    if db != 0:
        b_sc.set_offsets(blue)
    if dr != 0:
        r_sc.set_offsets(red)

#    ax.figure.canvas.draw()

    return b_sc, r_sc, txt


# FFwriter = animation.FFMpegWriter(fps=144)

ani = animation.FuncAnimation(fig, update, frames=range(1,100), interval=20,
                    init_func=init, blit=True)

这个小小的修改让 运行 对我来说很棒。多么有趣的计算圆周率的方法!