2013-02-06 107 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