【问题标题】:Matplotlib FuncAnimation for scatter plotMatplotlib FuncAnimation 用于散点图
【发布时间】:2015-01-09 15:00:07
【问题描述】:

我正在尝试使用 Matplotlib 的 FuncAnimation 为每帧动画显示一个点设置动画。

# modules
#------------------------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as py
from matplotlib import animation

py.close('all') # close all previous plots

# create a random line to plot
#------------------------------------------------------------------------------

x = np.random.rand(40)
y = np.random.rand(40)

py.figure(1)
py.scatter(x, y, s=60)
py.axis([0, 1, 0, 1])
py.show()

# animation of a scatter plot using x, y from above
#------------------------------------------------------------------------------

fig = py.figure(2)
ax = py.axes(xlim=(0, 1), ylim=(0, 1))
scat = ax.scatter([], [], s=60)

def init():
    scat.set_offsets([])
    return scat,

def animate(i):
    scat.set_offsets([x[:i], y[:i]])
    return scat,

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(x)+1, 
                               interval=200, blit=False, repeat=False)

很遗憾,最终的动画剧情与原版剧情不一样。在动画的每一帧中,动画情节也会闪烁几个点。关于如何使用animation 包正确设置散点图动画的任何建议?

【问题讨论】:

    标签: python python-3.x numpy matplotlib


    【解决方案1】:

    您的示例的唯一问题是如何在 animate 函数中填充新坐标。 set_offsets 需要 Nx2 ndarray 并且您提供了一个包含两个一维数组的元组。

    所以就用这个吧:

    def animate(i):
        data = np.hstack((x[:i,np.newaxis], y[:i, np.newaxis]))
        scat.set_offsets(data)
        return scat,
    

    并保存您可能想要调用的动画:

    anim.save('animation.mp4')
    

    【讨论】:

    • 效果很好。感谢您的帮助。我没有意识到set_offsets函数的要求。
    • 我的 xy 值是 Pythonic 的数字列表,因此 scat.set_offsets(np.c_[x, y]) 对我有用。
    【解决方案2】:

    免责声明,我编写了一个库来尝试简化此操作,但使用了ArtistAnimation,称为celluloid。您基本上像往常一样编写可视化代码,并在绘制每一帧后简单地拍照。这是一个完整的例子:

    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    import numpy as np
    from celluloid import Camera
    
    fig = plt.figure()
    camera = Camera(fig)
    
    dots = 40
    X, Y = np.random.rand(2, dots)
    plt.xlim(X.min(), X.max())
    plt.ylim(Y.min(), Y.max())
    for x, y in zip(X, Y):
        plt.scatter(x, y)
        camera.snap()
    anim = camera.animate(blit=True)
    anim.save('dots.gif', writer='imagemagick')
    

    【讨论】:

    • 除了 not 使用这个库会为你节省三行代码。所以它的范围似乎相当有限。
    • 我不知道你是怎么数 3 行的,但我不同意你的观点。我写了这个库,因为我每次尝试使用FuncAnimation 时都会花费至少一个小时。对我来说,节省时间比代码行更重要:)
    • 请注意,ArtistAnimation 非常昂贵。与 FuncAnimation 所需的单个艺术家相比,一个 2 分钟的 20 fps 动画在内存中创建了 2400 个艺术家,相当多。如果您了解其中的含义是可以的,但也许新用户会从了解 Func- 和 ArtistAnimation 之间的差异以及如何使用它们中受益更多,而不是使用可能会在以后造成麻烦的黑盒工具。我说的也是关于例如drawnow,它旨在简化事情,但会给几乎不了解它的作用的人带来问题。
    • 我同意你的观点。我认为它使用了更多内存,但我不确定如何量化它。我需要添加更多关于这些事情的免责声明。我需要更多地考虑从初学者到高级的过渡。想要超越 matplotlib 动画 api 的初学者用户的人可能不应该使用这个包。
    • 天哪,这太不可思议了。它也适用于seaborn地块。非常感谢。很高兴我找到了这篇文章。
    猜你喜欢
    • 1970-01-01
    • 2020-07-22
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多