2013-03-15 13 views
5

Mam bardzo podobny problem do this questionanimacje Saving Scatterplot z matplotlib produkuje plik puste wideo

ale proponowane rozwiązanie nie działa dla mnie.

Ustawiłem animowany wykres rozproszenia za pomocą modułu animacji matplotlib. Działa to dobrze, gdy wyświetla się na żywo. Chciałbym zapisać go w pliku Avi lub coś podobnego. Kod, który napisałem, aby to zrobić, nie jest błędny, ale wideo, które tworzy, pokazuje tylko pusty zestaw osi lub czarny ekran. Zrobiłem kilka czeków i dane są uruchamiane, a aktualizacja postaci jest po prostu nie zapisywana w wideo ...

Próbowałem usunąć "animated = True" i "blit = True" zgodnie z sugestią w this question, ale to nie naprawić problemu.

Podałem odpowiedni kod poniżej, ale w razie potrzeby mogę podać więcej. Czy ktoś mógłby zasugerować, co powinienem zrobić, aby to zadziałało?

def initAnimation(self): 
     rs, cfgs = next(self.jumpingDataStreamIterator)  
     #self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], marker='o') 
     self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], marker='o', animated=True) 
     return self.scat, 


def updateAnimation(self, i): 
    """Update the scatter plot.""" 
    rs, cfgs = next(self.jumpingDataStreamIterator) 
    # Set x and y data... 
    self.scat.set_offsets(rs[:2,].transpose()) 
    #self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], animated=True) 
    # Set sizes... 
    #self.scat._sizes = 300 * abs(data[2])**1.5 + 100 
    # Set colors.. 
    #self.scat.set_array(cfgs[0]) 
    # We need to return the updated artist for FuncAnimation to draw.. 
    # Note that it expects a sequence of artists, thus the trailing comma. 
    matplotlib.pyplot.draw() 
    return self.scat, 

def animate2d(self, steps=None, showEvery=50, size = 25): 
    self.figAnimation, self.axAnimation = matplotlib.pyplot.subplots() 
    self.axAnimation.set_aspect("equal") 
    self.axAnimation.axis([-size, size, -size, size]) 
    self.jumpingDataStreamIterator = self.jumpingDataStream(showEvery) 

    self.univeseAnimation = matplotlib.animation.FuncAnimation(self.figAnimation, 
          self.updateAnimation, init_func=self.initAnimation, 
          blit=True) 
    matplotlib.pyplot.show() 

def animate2dVideo(self,fileName=None, steps=10000, showEvery=50, size=25): 
    self.figAnimation, self.axAnimation = matplotlib.pyplot.subplots() 
    self.axAnimation.set_aspect("equal") 
    self.axAnimation.axis([-size, size, -size, size]) 
    self.Writer = matplotlib.animation.writers['ffmpeg'] 
    self.writer = self.Writer(fps=1, metadata=dict(artist='Universe Simulation')) 
    self.jumpingDataStreamIterator = self.jumpingDataStream(showEvery) 

    self.universeAnimation = matplotlib.animation.FuncAnimation(self.figAnimation, 
          self.updateAnimation, scipy.arange(1, 25), init_func=self.initAnimation) 

    self.universeAnimation.save('C:/universeAnimation.mp4', writer = self.writer) 
+0

mogłeś to zredukować aż do minimalnej ilości kodu, czego potrzeba, aby odtworzyć problem? Jest to wyraźnie część większej klasy i nie jest jasne, czy jest to funkcjonalny kod autonomiczny. Pomóż nam pomóc. – tacaswell

+0

kod _exact_ w http://stackoverflow.com/a/14740703/380231 działa lub nie działa, jeśli uruchomisz go w systemie? – tacaswell

+1

Przepraszamy za opóźnienie. Znalazłem pracę, po prostu zapisując wiele pojedynczych obrazów, a następnie wywołując ffmpeg, aby połączyć je razem. To nie jest idealne, ale wykonuje swoją pracę. Kiedy uruchomić kod tutaj http://stackoverflow.com/a/14740703/380231 pojawia się następujący błąd: .... pliku „C: \ Python27 \ lib \ site-packages \ matplotlib \ backend_bases .py”, linia 2093 w print_figure ** kwargs) pliku "C: \ \ \ lib Python27 site-pakiety \ matplotlib \ backends \ backend_agg.py" linia 483 w print_raw renderer._renderer.write_rgba (filename_or_obj) RuntimeError: Błąd zapisu do pliku – user2175850

Odpowiedz

0

Przepraszamy za opóźnienie. Znalazłem pracę, po prostu zapisując wiele pojedynczych obrazów, a następnie wywołując ffmpeg, aby połączyć je razem. To nie jest idealne, ale wykonuje swoją pracę. (Część większej klasy)

def easyway(self, frames): 
    ##INSERT CODE TO GET xdata and ydata! 
    for i in range(0, frames): 
     fileName = "videoName"+"%04d.png" % i 
     matplotlib.pyplot.scatter(xdata,ydata,c=coldata, marker='*', 
           s=15.0, edgecolor='none') 
     matplotlib.pyplot.savefig(self.workingDirectory+'temp/'+fileName, dpi=dpi) 
     matplotlib.pyplot.close() 
     ##INSERT CODE TO UPDATE xdata and ydata! 
    self.createVideoFile(fps)#calls FFMpeg to chain together all the pictures 

    if cleanUp:#removes all the picture files created in the process 
     print "temporary picture files being removed..." 
     self.clearDirectory() 
    print "FINISHED" 

def clearDirectory(self,directoryName='temp'): 
    files = glob.glob(self.workingDirectory+directoryName+"/*") 
    for f in files: 
     os.remove(f) 

def createVideoFile(self,fps=3): 
    command="ffmpeg -f image2 -r %s -i %s%s" % (str(fps), self.workingDirectory+'temp/', self.universe.description) 
    command+="%04d.png" 
    command+=" -c:v libx264 -r 30 %s.mp4" % (self.workingDirectory+'videos/'+self.universe.description) 
    print "Running command:" 
    print command 
    p = subprocess.Popen(command, shell=True, stdout = subprocess.PIPE, stderr=subprocess.STDOUT) 
    output = p.communicate()[0] 
    print "output\n"+"*"*10+"\n" 
    print output 
    print "*"*10 
    print "Video file has been written"