2013-02-06 11 views
5

나는 matplotlib로 애니메이션 산란계를 저장하려고 시도해 왔으며 애니메이션 그림으로보고 사본을 저장하기 위해 완전히 다른 코드가 필요하지 않았 으면 좋겠습니다. 이 그림은 저장이 완료된 후 완벽하게 모든 데이터 포인트를 보여줍니다.matplotlib로 산점도 애니메이션 저장하기

이 코드는 Matplotlib 3D scatter color lost after redrawYann's answer의 색상에 대한 수정과 Animating 3d scatterplot in matplotlibGiggi's의 수정 된 버전입니다 (색상은 내 비디오에 중요 할 것이기 때문에, 그래서 나는 그들이 작동 있는지 확인하려면).

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가 생성되었지만 축을 제외하고 4 초 동안 모두 비어 있습니다. 실제 인물은 항상 내가보고 싶은 것을 정확하게 보여줍니다. 저장 함수의 플롯을 정상적으로 움직이는 애니메이션을 채우는 것과 같은 방법으로 채울 수 있습니까? 아니면 matplotlib에서도 가능합니까?

편집 :이 (이니셜 라이저에서와 경계를 설정하지 않고) 업데이트에 분산 호출을 사용하여, 그것은 단지에 표시되지 않는 것, 축이 데이터마다 실행되고 있음을 보여, 성장 표시하는 아비의 원인 동영상 자체 Python 2.7.3에서 matplotlib 1.1.1rc를 사용하고 있습니다.

+0

당신이 당신의 들여 쓰기를 해결할 수 : 아래

내가 도망 내가 예상 출력 동영상을 가지고 정확히 무엇입니까? – tacaswell

+0

와우. 나는 더 조심해서 복사하고 붙여야한다. 필자의 소스에는 탭이 아닌 공백이 있지만 어떤 일이 발생했는지는 알 수 없습니다. – Poik

+0

그림과 같이 보시면이 모양이 괜찮아 보입니까? 어떤 MPL 버전을 사용하고 있습니까? – tacaswell

답변

2

blit=TrueFuncAnimationanimated=True에서 scatter까지 제거하면 작동합니다. 나는 업데이트해야하는 아티스트 만 프레임 사이에서 업데이트/다시 그려지는 로직을 사용하는 것이 잘못되었다고 생각합니다.

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 및 Matplotlib 1.2.1에서는 작동하지 못했습니다. 새로운 포인트 또는 빈 플롯으로 덮어 쓰게 된 오래된 포인트 톤을 가진 비디오를 만드는 것이 좋을 것입니다. 내 비디오에 링크 된 코드를 사용해보십시오. https://www.youtube.com/watch?v=dCIOOjJ1Sk0 마침내 CamStudio를 사용했는데 더 잘 작동하고 고품질의 비디오 출력이 가능했습니다. – Demolishun