也许你可以帮我。我正在尝试在matplotlib中为一些酒吧和情节制作动画。例如,下面的一些代码(仅条形图)可以正常工作:
from matplotlib import pyplot as plt
from matplotlib.animation import ArtistAnimation
import numpy as np
fig = plt.figure()
x = [1,2,3,4,5]
y = [5,7,2,5,3]
y_steps = []
for i in range(len(y)):
y_steps.append(np.linspace(0, y[i], 50))
data = []
for i in range(len(y_steps[0])):
data.append([y_steps[j][i] for j in range(len(y))])
ims = []
for i in range(len(y_steps[0])):
pic = plt.bar(x, data[i], color='c')
ims.append(pic)
anim = ArtistAnimation(fig, ims, interval=40)
plt.show()
但是现在我希望一些线条与条形一起增长。我已经尝试了很多,并且用谷歌搜索了很多,但是我无法使其工作。
为了您的理解,我在这里粘贴我的想法(非工作代码):
from matplotlib import pyplot as plt
from matplotlib.animation import ArtistAnimation
import numpy as np
fig = plt.figure()
x = [1,2,3,4,5]
y = [5,7,2,5,3]
y_steps = []
for i in range(len(y)):
y_steps.append(np.linspace(0, y[i], 50))
data = []
for i in range(len(y_steps[0])):
data.append([y_steps[j][i] for j in range(len(y))])
ims = []
for i in range(len(y_steps[0])):
pic_1 = plt.bar(x, data[i], color='c')
pic_2 = plt.plot(x, data[i], color='r')
ims.append([pic_1, pic_2])
anim = ArtistAnimation(fig, ims, interval=40)
plt.show()
看起来所有显示在ims中的图片都立即显示出来,并且没有动画。
也许有人可以帮助我。
非常感谢。
最佳答案
使用ArtistAnimation(fig, ims, ...)
时,ims
is expected to be a list of Artists。[pic_1, pic_2]
是列表,而不是艺术家。ims.append([pic_1, pic_2])
将列表作为单个对象附加到ims
。
解决该问题的最简单方法是将ims.append([pic_1, pic_2])
更改为
ims.extend([pic_1, pic_2])
因为
ims.extend([pic_1, pic_2])
将pic_1
和pic_2
分别追加到ims
中。通过玩这个例子,您可以看到
append
和extend
之间的区别:In [41]: x = []
In [42]: x.append([1, 2])
In [43]: x
Out[43]: [[1, 2]] # x is a list containing 1 item which happens to be a list
In [44]: y = []
In [45]: y.extend([1,2])
In [46]: y
Out[46]: [1, 2] # y is a list containing 2 items
尽管这提供了快速解决方案,但结果相当“眨眼”。
要使动画更流畅,请避免多次调用
plt.bar
和plt.plot
。一次调用一次,然后使用
Rectangle.set_height
和Line2D.set_data
方法修改现有的Rectangles
和Line2Ds
效率更高:from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
fig = plt.figure()
x = [1,2,3,4,5]
y = [5,7,2,5,3]
data = np.column_stack([np.linspace(0, yi, 50) for yi in y])
rects = plt.bar(x, data[0], color='c')
line, = plt.plot(x, data[0], color='r')
plt.ylim(0, max(y))
def animate(i):
for rect, yi in zip(rects, data[i]):
rect.set_height(yi)
line.set_data(x, data[i])
return rects, line
anim = animation.FuncAnimation(fig, animate, frames=len(data), interval=40)
plt.show()