我一直在尝试用matplotlib保存一个动画散点图,我希望它不需要完全不同的代码来查看动画图和保存副本。图中显示了保存完成后的所有数据点。
此代码是Animating 3d scatterplot in matplotlib上的Giggi's的修改版本,修复了Matplotlib 3D scatter color lost after redraw上的Yann's answer的颜色(因为颜色在我的视频中很重要,所以我想确保它们可以工作)。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
FLOOR = -10
CEILING = 10
class AnimatedScatter(object):
def __init__(self, numpoints=5):
self.numpoints = numpoints
self.stream = self.data_stream()
self.angle = 0
self.fig = plt.figure()
self.fig.canvas.mpl_connect('draw_event',self.forceUpdate)
self.ax = self.fig.add_subplot(111,projection = '3d')
self.ani = animation.FuncAnimation(self.fig, self.update, interval=100,
init_func=self.setup_plot, blit=True,frames=20)
def change_angle(self):
self.angle = (self.angle + 1)%360
def forceUpdate(self, event):
self.scat.changed()
def setup_plot(self):
X = next(self.stream)
c = ['b', 'r', 'g', 'y', 'm']
self.scat = self.ax.scatter(X[:,0], X[:,1], X[:,2] , c=c, s=200, animated=True)
self.ax.set_xlim3d(FLOOR, CEILING)
self.ax.set_ylim3d(FLOOR, CEILING)
self.ax.set_zlim3d(FLOOR, CEILING)
return self.scat,
def data_stream(self):
data = np.zeros(( self.numpoints , 3 ))
xyz = data[:,:3]
while True:
xyz += 2 * (np.random.random(( self.numpoints,3)) - 0.5)
yield data
def update(self, i):
data = next(self.stream)
#data = np.transpose(data)
self.scat._offsets3d = ( np.ma.ravel(data[:,0]) , np.ma.ravel(data[:,1]) , np.ma.ravel(data[:,2]) )
plt.draw()
return self.scat,
def show(self):
plt.show()
if __name__ == '__main__':
a = AnimatedScatter()
a.ani.save("movie.avi", codec='avi')
a.show()
这样就生成了一个完全有效的.avi,但是除了坐标轴之外,它在四秒钟内都是空白的。实际的数字总是准确地显示我想看到的。我怎样才能像填充一个正常运行的动画一样填充保存函数的图,或者在matplotlib中可以吗?
**EDIT:**在更新中使用scatter调用(不像初始化器那样设置边界)会导致.avi显示轴增长,显示数据每次都在运行,只是没有显示在视频本身上。我正在使用matplotlib 1.1.1rc和Python 2.7.3。
1条答案
按热度按时间cbjzeqam1#
从
FuncAnimation
中删除blit=True
,从scatter
中删除animated=True
,它就可以工作了。我怀疑逻辑出了问题,确保只有需要更新的艺术家才能在帧之间更新/重绘(而不仅仅是重绘所有内容)。下面是我运行的内容,我得到了预期的输出电影: