2013-02-06 20 views
5

मैं matplotlib के साथ एक एनिमेटेड scatterplot को बचाने की कोशिश कर रहा है, और मैं पसंद करेंगे कि यह एक एनिमेटेड व्यक्ति के रूप में देखने के लिए और एक प्रति को बचाने के लिए पूरी तरह से अलग कोड की जरूरत नहीं थी साथ सहेजा जा रहा है scatterplot एनिमेशन। सहेजने के बाद आंकड़ा पूरी तरह से सभी डेटापॉइंट्स दिखाता है।matplotlib

इस कोड Animating 3d scatterplot in matplotlib पर Giggi's का एक संशोधित संस्करण, पर Matplotlib 3D scatter color lost after redrawYann'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 कुल्हाड़ियों, बढ़ रही है दिखा रहा है कि डेटा हर बार चलाया जा रहा है दिखाने के लिए कारण बनता है, यह सिर्फ पर नहीं दिखाया जा रहा है वीडियो खुद ही। मैं अजगर 2.7.3 के साथ matplotlib 1.1.1rc उपयोग कर रहा हूँ।

+0

आप अपने खरोज ठीक कर सकते हैं:

नीचे मैं क्या भाग गया और मैं उम्मीद उत्पादन फिल्म मिल गया ठीक है? – tacaswell

+0

हूप्स। मुझे और अधिक सावधानीपूर्वक प्रतिलिपि बनाना और पेस्ट करना चाहिए। हालांकि मेरे स्रोत में टैब की बजाय रिक्त स्थान हैं, इसलिए मुझे नहीं पता कि क्या हुआ। – Poik

+0

और यह ठीक लग रहा है अगर आप इसे एक चित्र में देखते हैं? आप एमपीएल का किस संस्करण का उपयोग कर रहे हैं? – tacaswell

उत्तर

2

और animated=True से से blit=True हटाएं और यह काम करता है। मुझे लगता है कुछ तर्क के साथ गलत हो रहा यकीन है कि केवल कलाकारों अद्यतन करने की आवश्यकता है कि अपडेट किया जाता है/फ्रेम के बीच दोबारा बनाई (बस फिर से ड्राइंग सब कुछ कहने के बजाय) करता है कि नहीं है।

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' को हटाने में मदद मिलती है, एनीमेशन.save कोड '_draw_next_frame' को कॉल करते समय' blit' को गलत पर सेट करता है। जब मुझे मौका मिलता है तो मैं matplotlib की साइट पर पूर्ण बग रिपोर्ट (या कम से कम विशलिस्ट अनुरोध) जोड़ दूंगा। – Poik

+0

SciPy 0.12.0, Numpy 1.7.1, और Matplotlib 1.2.1 के साथ मैं इसे काम नहीं कर सका। यह सर्वोत्तम रूप से नए अंक या रिक्त साजिश द्वारा ओवरराइट किए गए पुराने बिंदुओं के एक टन के साथ एक वीडियो बना देगा। मेरे वीडियो पर लिंक किए गए कोड को आजमाने के लिए आपका स्वागत है: https://www.youtube.com/watch?v=dCIOOjJ1Sk0 मैंने आखिरकार कैमस्टूडियो का उपयोग किया और यह बेहतर काम किया और उच्च गुणवत्ता वाला वीडियो आउटपुट था। – Demolishun