更新 python 动画时删除先例散点图

Remove precedent scatterplot while updating python animation

虽然浏览 Whosebug 的时间确实改进了我的 python 动画代码,但我还是不太明白一件事,因此我转向社区的好心人,希望有人能够粉碎一些光线。

简而言之,我有一个大约 2000 x 1000 像素的背景图像,比方说,我需要在该图像上散布一些点并制作动画过程并将整个过程保存为视频。我只能根据需要更新散点图,但我无法删除先例散点图。所以输出不是我真正想要的。如果有人能看一眼代码并找出问题所在,我会很高兴。我用过 scat.remove() 似乎什么也没做。

提前谢谢大家。

import matplotlib.pyplot as plt
import pylab as pl
import numpy as np
from pylab import savefig
from matplotlib import animation
import matplotlib



######################################################
fig = plt.figure()
ax = plt.axes()
a = plt.imread('background.jpg')    
im = plt.imshow(a)

#######################################################

def randpair(n):
    x,y=[],[]
    for i in xrange(n):
        x.append(np.random.randint(100,1900))
        y.append(np.random.randint(100,900))
    return x,y


def animate(i):

    scat = ax.scatter(0,0,color='white')
    points = np.random.randint(5,size=10)

    for j in points: 
        xy = randpair(j)
        x = xy[0]
        y = xy[1]
        print x,y

        if len(x) > 0 :
            scat.remove()
            scat = ax.scatter(x,y,color='r',s=18)


        plt.xticks([])
        plt.yticks([])



    return scat,ax,  # ax returns the text to be updated and scat returns the scatterplot.


anim = animation.FuncAnimation(fig, animate, 49,interval=300, blit=True)
writer = animation.writers['ffmpeg']
anim.save('film_3.mp4')
#plt.show()

在代码中,您已经在循环结束前移除了最后一个散点图;所以会添加一些散点图,然后立即删除。
可以通过在列表中收集散点,然后使用 remove 从 canvas 中删除列表中的散点并清理列表来防止这种情况。

除此之外,返回完整的 ax 对象有点没用。所以我建议简单地关闭 blitting,因为保存动画并不重要。

这是对我有用的完整代码:

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

fig = plt.figure()
ax = plt.axes()
scats = []
a = np.random.rand(8,18)
im = ax.imshow(a, cmap="YlGn", vmin=0, vmax=3, extent=[0,2000,0,1000])
plt.xticks([])
plt.yticks([])

def randpair(n):
    x,y=[],[]
    for i in xrange(n):
        x.append(np.random.randint(100,1900))
        y.append(np.random.randint(100,900))
    return x,y

def animate(i):
    global scats
    # first remove all old scatters
    for scat in scats:
        scat.remove()
    scats=[]
    # now draw new scatters
    points = np.random.randint(5,size=10)
    for j in points: 
        x, y = randpair(j)
        if len(x) > 0 :
            scats.append(ax.scatter(x,y,color='r',s=18))  

anim = matplotlib.animation.FuncAnimation(fig, animate, 50,
                                interval=1000, blit=False)

writer = matplotlib.animation.FFMpegWriter(fps=15, 
            codec="h264", 
            extra_args=["-preset", "veryslow","-crf","0"])
anim.save(__file__+".mp4", writer=writer)

plt.show()