2010-09-02 15 views
25

निर्दिष्ट करते समय स्मृति जारी नहीं किया जा रहा है मैं संख्यात्मक सिमुलेशन के परिणामों के कई भूखंड उत्पन्न करने के लिए matplotlib का उपयोग कर रहा हूँ। भूखंडों एक वीडियो में फ्रेम के रूप में उपयोग किया जाता है, और इसलिए मैं बार-बार एक समारोह बुला इस एक के समान द्वारा उनमें से कई पैदा कर रहा हूँ:पायथन matplotlib: आकृति आकार

from pylab import * 

def plot_density(filename,i,t,psi_Na): 
    figure(figsize=(8,6)) 
    imshow(abs(psi_Na)**2,origin = 'lower') 
    savefig(filename + '_%04d.png'%i) 
    clf() 

समस्या यह है कि अजगर की प्रक्रिया के स्मृति उपयोग एक से बढ़ता है इस समारोह में प्रत्येक कॉल के साथ मेगाबाइट्स के जोड़े। उदाहरण के लिए अगर मैं इस पाश से कॉल करने की:

if __name__ == "__main__": 
    x = linspace(-6e-6,6e-6,128,endpoint=False) 
    y = linspace(-6e-6,6e-6,128,endpoint=False) 
    X,Y = meshgrid(x,y) 
    k = 1000000 
    omega = 200 
    times = linspace(0,100e-3,100,endpoint=False) 
    for i,t in enumerate(times): 
     psi_Na = sin(k*X-omega*t) 
     plot_density('wavefunction',i,t,psi_Na) 
     print i 

तो राम उपयोग 600MB करने के लिए समय के साथ बढ़ता है। यदि मैं फ़ंक्शन परिभाषा में figure(figsize=(8,6)) पंक्ति पर टिप्पणी करता हूं, तो राम उपयोग 52 एमबी पर स्थिर रहता है। (8,6) डिफ़ॉल्ट आकृति आकार है और इसलिए दोनों छवियों में समान छवियां उत्पन्न की जाती हैं। मैं अपने संख्यात्मक डेटा से रैम से बाहर किए बिना अलग-अलग आकार के प्लॉट बनाना चाहता हूं। मैं इस स्मृति को मुक्त करने के लिए पायथन को कैसे मजबूर कर सकता हूं?

मैं gc.collect() प्रत्येक पाश की कोशिश की है कचरा संग्रहण के लिए मजबूर करने, और मैं f = gcf() की कोशिश की है वर्तमान आंकड़ा पाने के लिए और उसके बाद del f इसे हटाने के लिए है, लेकिन कोई लाभ नहीं हुआ।

मैं 64 बिट उबंटू 10.04 पर सीपीथन 2.6.5 चला रहा हूं।

उत्तर

35
pylab.figure के लिए docstring से

:

In [313]: pylab.figure? 

आप कई आंकड़े बना रहे हैं, बनाने के सुनिश्चित करें कि आप स्पष्ट रूप से कहते हैं "बंद" पर आंकड़े आप प्रयोग नहीं कर रहे हैं, क्योंकि इस pylab सक्षम हो जाएगा ठीक से मेमोरी को साफ करें।

तो शायद कोशिश:

pylab.close()  # closes the current figure 
+0

यह करता है यही कारण है! बहुत बहुत धन्यवाद। –

+2

हां, 'clf' आकृति को हटा नहीं देता है या इसके संसाधनों को जारी नहीं करता है, यह केवल इसे साफ़ करता है। और 'एफ = जीसीएफ(); डेल एफ 'केवल आपके द्वारा बनाए गए संदर्भ को हटा देता है, यह आंकड़ा ऑब्जेक्ट को ही हटा नहीं देता है। यही है कि आपको 'बंद' की आवश्यकता है। (+1) –

9

एक आंकड़ा समापन निश्चित रूप से एक विकल्प है, हालांकि, कई बार दोहराया, इस समय लगता है। मेरा सुझाव है कि एक लगातार छवि वस्तु (static function variable के माध्यम से, या अतिरिक्त फ़ंक्शन तर्क के रूप में) हो। यदि वह ऑब्जेक्ट fig है, तो फ़ंक्शन fig.clf()को प्रत्येक प्लॉटिंग चक्र से पहले कॉल करेगा।

from matplotlib import pylab as pl 
import numpy as np 

TIMES = 10 
x = np.linspace(-10, 10, 100) 
y = np.sin(x) 
def withClose(): 
    def plotStuff(i): 
     fig = pl.figure() 
     pl.plot(x, y + x * i, '-k') 
     pl.savefig('withClose_%03d.png'%i) 
     pl.close(fig) 
    for i in range(TIMES): 
     plotStuff(i) 


def withCLF(): 
    def plotStuff(i): 
     if plotStuff.fig is None: 
      plotStuff.fig = pl.figure() 
     pl.clf() 
     pl.plot(x, y + x * i, '-') 
     pl.savefig('withCLF_%03d.png'%i) 
    plotStuff.fig = None 

    for i in range(TIMES): 
     plotStuff(i) 

यहाँ समय को महत्व देता

In [7]: %timeit withClose() 
1 loops, best of 3: 3.05 s per loop 

In [8]: %timeit withCLF() 
1 loops, best of 3: 2.24 s per loop 
+1

अच्छा। अब मुझे यह स्पष्ट है कि मेरे मूल उदाहरण में 'आकृति()' के लिए प्रत्येक कॉल के साथ मैं एक नया आंकड़ा बना रहा था और पुराने को बंद नहीं कर रहा था। साथ ही संदर्भ पर लटकने के साथ, कोई भी संख्या तर्क प्रदान कर सकता है: 'आंकड़ा (0, अंजीर = जो कुछ भी)' यह सुनिश्चित करने के लिए कि हर बार एक ही आंकड़ा इस्तेमाल किया जा रहा हो। –

संबंधित मुद्दे