2013-03-15 4 views
5

Ich bin ein sehr ähnliches Problem zu this question mitSaving Scatterplot Animationen mit matplotlib produzieren leere Videodatei

aber die vorgeschlagene Lösung ist für mich nicht.

Ich habe ein animiertes Streudiagramm mit dem Matplotlib-Animationsmodul eingerichtet. Dies funktioniert gut, wenn es live angezeigt wird. Ich möchte es in einer AVI-Datei oder ähnlichem speichern. Der Code, den ich geschrieben habe, um dies zu tun, ist kein Fehler, aber das Video, das er erzeugt, zeigt nur einen leeren Achsensatz oder einen schwarzen Bildschirm. Ich habe mehrere Überprüfungen durchgeführt und die Daten werden ausgeführt und die Zahl wird aktualisiert. Es wird nicht in Video gespeichert ...

Ich habe versucht, "animated = True" und "blit = True" zu entfernen, wie in this question vorgeschlagen, aber das tat behebe das Problem nicht.

Ich habe den entsprechenden Code unten platziert, kann aber bei Bedarf mehr liefern. Könnte jemand vorschlagen, was ich tun sollte, damit das funktioniert?

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

Können Sie dies auf die minimale Menge an Code reduzieren, die Sie benötigen, um das Problem zu reproduzieren? Dies ist eindeutig Teil einer größeren Klasse, und es ist nicht klar, dass dies als Standalone-Code funktioniert. Bitte helfen Sie uns, Ihnen zu helfen. – tacaswell

+0

funktioniert der _exact_ code in http://stackoverflow.com/a/14740703/380231 funktioniert oder nicht funktioniert, wenn Sie es auf Ihrem System ausführen? – tacaswell

+1

Entschuldigung für die Verzögerung. Ich habe eine Arbeit gefunden, indem ich einfach viele einzelne Bilder gespeichert habe und dann ffmpeg aufgerufen habe, um sie zusammen zu ketten. Dies ist nicht ideal, aber erledigt die Arbeit. Wenn ich den Code hier laufen http://stackoverflow.com/a/14740703/380231 Ich erhalte die folgende Fehlermeldung: .... Datei „C: \ Python27 \ lib \ site-packages \ matplotlib \ backend_bases .py ", Zeile 2093, in print_figure ** kwargs) Datei" C: \ Python27 \ lib \ Site-Pakete \ matplotlib \ Backends \ backend_agg.py ", Zeile 483, in print_raw renderer._renderer.write_rgba (Dateiname_oder_obj) RuntimeError: Fehler beim Schreiben in Datei – user2175850

Antwort

0

Entschuldigung für die Verzögerung. Ich habe eine Arbeit gefunden, indem ich einfach viele einzelne Bilder gespeichert habe und dann ffmpeg aufgerufen habe, um sie zusammen zu ketten. Dies ist nicht ideal, aber erledigt die Arbeit. (Teil einer größeren Klasse)

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"