2013-02-06 69 views
5

我一直在试图用matplotlib保存动画散点图,我宁愿它不需要完全不同的代码来查看动画图形和保存副本。完成保存后,该图完美地显示了所有数据点。用matplotlib保存scatterplot动画

此代码是Giggi'sAnimating 3d scatterplot in matplotlib的改良版,与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中使用?

编辑:在更新使用分散调用(无设置范围为在初始化)导致的.avi显示轴增长,显示出的数据每次被运行,它只是不显示在视频本身。 我在Python 2.7.3中使用matplotlib 1.1.1rc。

+0

您可以修复你的缩进? – tacaswell

+0

哎呦。我应该更仔细地复制和粘贴。尽管我的源代码使用空格而不是制表符,但我不知道发生了什么。 – Poik

+0

,如果你在一个图中看它,这看起来好吗?你使用的是什么版本的MPL? – tacaswell

回答

2

删除blit=TrueFuncAnimationanimated=Truescatter它的工作原理。我怀疑逻辑有问题,确保只有需要更新的艺术家才能在帧之间更新/重绘(而不是仅仅重绘所有内容)。

下面就是我跑了,我得到了预期的输出影片:

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, 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) 

     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) 
     self.scat._offsets3d = (np.ma.ravel(data[:,0]) , np.ma.ravel(data[:,1]) , np.ma.ravel(data[:,2])) 
     return self.scat, 

    def show(self): 
     plt.show() 

if __name__ == '__main__': 
    a = AnimatedScatter() 
    a.ani.save("movie.avi", codec='avi') 
    a.show() 
+0

这个伎俩!而我的实际项目与该修补程序一起工作。谢谢! – Poik

+0

有趣的是,删除'blit'有助于考虑animation.save代码在调用'_draw_next_frame'时将'blit'设置为false。当我有机会的时候,我会向matplotlib的网站添加完整的错误报告(或者至少希望列表请求)。 – Poik

+0

使用SciPy 0.12.0,Numpy 1.7.1和M​​atplotlib 1.2.1我无法使它工作。充其量只会创建一个视频,其中有许多旧点被新点或空白图覆盖。欢迎您尝试在我的视频中链接的代码:https://www.youtube.com/watch?v = dCIOOjJ1Sk0我最终使用了CamStudio,它运行得更好,并且具有更高质量的视频输出。 – Demolishun