我正在尝试学习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'
答案 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)