Scatterplot-Animationen mit Matplotlib speichern

Ich habe versucht, ein animiertes Scatterplot mit Matplotlib zu speichern, und ich würde es vorziehen, dass es keinen ganz anderen Code für die Anzeige als animierte Figur und zum Speichern einer Kopie benötigt hat. Die Figur zeigt alle Datenpunkte perfekt, nachdem das Speichern abgeschlossen ist.

Dieser Code ist eine modifizierte Version von Giggi's auf Animating 3d Scatterplot in Matplotlib , mit einem Fix für die Farben von Yann's Antwort auf Matplotlib 3D Scatter Farbe verloren nach redraw (weil Farben werden wichtig auf meinem Video, so möchte ich sicherstellen, dass sie arbeiten ).

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

Hierdurch wird ein vollkommen gültiges .avi erzeugt, aber es ist für alle vier Sekunden mit Ausnahme der Achsen leer. Die tatsächliche Figur zeigt immer genau das, was ich sehen möchte. Wie kann ich die Plots der Save-Funktion auf die gleiche Weise bevölkern, wie ich eine normal laufende Animation bevölkert oder ist es in Matplotlib möglich?

EDIT: Mit einem Scatter-Aufruf im Update (ohne die Begrenzung wie im Initialisierer zu setzen) wird die .avi angezeigt, um die Achsen zu vergrößern, die zeigen, dass die Daten jedes Mal ausgeführt werden, es wird einfach nicht auf dem Video selbst angezeigt. Ich benutze matplotlib 1.1.1rc mit Python 2.7.3.

One Solution collect form web for “Scatterplot-Animationen mit Matplotlib speichern”

Entfernen blit=True von FuncAnimation und animated=True von scatter und es funktioniert. Ich vermute, dass es etwas falsch mit der Logik gibt, die sicherstellt, dass nur die Künstler, die aktualisiert werden müssen, zwischen Frames aktualisiert / neu gezeichnet werden (anstatt nur alles neu zu zeichnen).

Unten ist genau das, was ich lief und ich habe den erwarteten Ausgang Film:

 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() 
  • Matplotlib 3D Scatterplot mit Markerfarbe entsprechend RGB-Werten
  • Wie wähle ich einen Punkt in einem Subplot aus und markiere ihn in benachbarten Subplots in Matplotlib (Erweiterung zum Punktbereich)
  • Pylab 3d scatter plots mit 2d projektionen von gezeichneten daten
  • Ausrichten matplotlib Scatter Marker links und rechts
  • Fixierung der Farbe in Scatter-Plots in Matplotlib
  • Ungültige rgba arg "#" in matplotlib
  • Problem beim Einstellen der Hintergrundfarbe in pyqtgraph
  • Einstellen der verschiedenen Farbe für jede Serie im Streudiagramm auf Matplotlib
  • Scatterplot mit unterschiedlicher Größe, Marker und Farbe aus Pandas Dataframe
  • Probleme mit markevery - AttributeError: Unbekannte Eigenschaft markevery
  • Gibt es eine Funktion, um Matratzen in Matplotlib zu machen?
  • Python ist die beste Programmiersprache der Welt.