从一组预先计算的绘图中创建动画:ArtistAnimation

时间:2018-12-27 04:30:39

标签: python matplotlib

我正在尝试学习Matplotlib的某些动画功能。

请考虑这种尝试绘制动画的正弦和余弦曲线幅度增加的尝试。

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

fig = plt.figure()


ims = []
x   = np.linspace(0,10,20)
for i in range(60):
    y1 = map (lambda t: i*np.sin(t) , x)
    y2 = map (lambda t: i*np.cos(t) , x)

    im1 = plt.plot(x, y1, 'bo-')
    im2 = plt.plot(x, y2, 'go-')

    ims.extend([im1,im2])

ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)

plt.show()

这为我绘制了蓝色正弦曲线和绿色余弦曲线的交替集。如果尝试绘制它们,您将看到结果绘制是一种正弦和余弦之间非常快速的交替图像集。

我知道这里可能是ims.extend([im1,im2])这是有问题的命令。但是,当我使用.extend代替.append()时,使ims成为图像列表的列表,我得到了错误

Traceback (most recent call last):
  File "dynamic_image.py", line 29, in <module>
    ani.save("movie.mp4")
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 1254, in save
    anim._init_draw()
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 1618, in _init_draw
    artist.set_visible(False)
AttributeError: 'list' object has no attribute 'set_visible'

2 个答案:

答案 0 :(得分:1)

我不确定原因,但是如果您只想要结果,则可以尝试以下代码。如果您确实需要知道原因,请等待其他人是否可以回答。

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

fig, ax = plt.subplots()
x = np.linspace(0, 10, 50)
line1, = ax.plot(x, np.sin(x), 'bo-')
line2, = ax.plot(x, np.cos(x), 'go-')
ax.set_ylim(-60, 60)

def init():
    line1.set_ydata([np.nan] * len(x))
    line2.set_ydata([np.nan] * len(x))
    return [line1, line2]

def animate(i):
    line1.set_ydata(i * np.sin(x))
    line2.set_ydata(i * np.cos(x))
    return [line1, line2]

ani = animation.FuncAnimation(fig, animate, init_func=init, 
                              blit=True, frames=60, repeat=True,
                              interval=50, repeat_delay=1000)
ani.save('result.mp4')

答案 1 :(得分:0)

问题是从plt.plot返回的值是一个列表。例如,im1将如下所示:

[<matplotlib.lines.Line2D at 0x11a0f62e8>]

将歌手添加到列表中时,将分别添加两个歌手。因此,更改此行:

ims.extend([im1,im2])

对此:

ims.extend([im1 + im2])

现在ims的长度是60,而不是120,并且余弦和正弦将一起绘制。

我写了一个库来简化这个过程,名为celluloid。这是一个黑匣子,所以如果您的目标是学习matplotlib,则可能要跳过。如果您决定使用它,还请阅读限制。这是复制动画的代码:

from celluloid import Camera
fig = plt.figure()
camera = Camera(fig)
x   = np.linspace(0,10,20)
for i in range(60):
    plt.plot(x, i*np.sin(x), 'go-')
    plt.plot(x, i*np.cos(x), 'bo-')
    camera.snap()
ani = camera.animate(interval=50, blit=True, repeat_delay=1000)