2012-07-26 36 views
1

我遇到了,我一直在試圖解決現在幾天蟒蛇錯誤時,底層的C/C++對象已被刪除。 我的程序會創建數字,保存並關閉它們,除了這個錯誤外,它可以正常工作。通常它不會妨礙保存過程,但有時保存時圖片會丟失較低部分。奇怪的是,這只是發生在循環到達savefig方法每一秒的時間,這裏是我的代碼:RuntimeError:保存和事後關閉pyplot數字

for num in np.arange(file_number): 
    plt.figure('abc' + str(num),figsize=(22,12),dpi=100) 
    #some plots are added to the figure 
    print 1 
    plt.savefig(os.path.join(savepath,filename),dpi=100) 
    print 2 
    plt.close()                  
    print 3 

我使用的打印命令,看看那裏的錯誤發生。這裏是Spyder的控制檯輸出:

Reading file1.file 
1 
2 
3 
Reading file2.file 
1 
Traceback (most recent call last): 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_qt4.py", line 151, in <lambda> 
    lambda: self.close_event()) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1564, in close_event 
    self.callbacks.process(s, event) 
RuntimeError: underlying C/C++ object has been deleted 
2 
3 
Reading file3.file 
1 
2 
3 
Reading file4.file 
1 
Traceback (most recent call last): 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_qt4.py", line 151, in <lambda> 
    lambda: self.close_event()) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1564, in close_event 
    self.callbacks.process(s, event) 
RuntimeError: underlying C/C++ object has been deleted 
2 
3 

據我瞭解,誤差在保存圖形(每秒一次)已經出現,雖然它工作正常,如果我忽略的close()命令。在這種情況下,我的RAM在大約70個文件後被填充,有時我需要評估幾百個文件。這就是爲什麼我需要包含close()命令或類似的東西。 如果你解決這個問題(或者改進我的程序,我想我這樣做的保存和關閉的方式可能會被認爲是醜陋的),請幫助我。

+0

如果刪除了'plt.close()'會發生什麼?或者,如果使用fig.savefig(...)方法而不是pyplot函數會發生什麼情況。你是否在做其他的事情,比如添加回調等?什麼版本的matplotlib? – pelson 2012-07-26 22:05:30

+0

當我刪除'plt.close()'時,程序沒有錯誤。然而,我的內存得到填充非常快,直到我關閉應用程序才被釋放。一旦它接近完整,程序速度減慢一個很大的因素,並且計算機上的其他應用程序幾乎不可用。 'fig.savefig(...)'不會改變任何東西。 我不太清楚你的意思是「添加回調」。 Matplotlib的版本是1.1.1rc – 2012-07-27 11:10:28

回答

0

如何改變後端到其他的選擇嗎?例如:

import matplotlib as mpl 
mpl.use("agg") 

from matplotlib import pyplot as plt 
import numpy as np 

print plt.get_backend() 

file_number = 100 
for num in np.arange(file_number): 
    plt.figure('abc' + str(num),figsize=(22,12),dpi=100) 
    #some plots are added to the figure 
    print 1 
    plt.savefig("%d.png" % num,dpi=100) 
    print 2 
    plt.close() 
    print 3 
+0

謝謝,這解決了這個問題,雖然我不確定,後端的變化真的在做什麼(我讀了一些關於更好的圖像質量,我認爲)。但是,我不能再使用show()命令了(我想在循環結尾顯示一些數據摘要,這是一個單獨的數字)。我在agg後臺發現的文檔說了一些關於agg不是交互式後端的內容,這是否意味着我不能在屏幕上顯示任何圖像,只需保存它們即可? – 2012-07-27 11:00:56

+0

Agg後端不是交互式後端。您可以保存摘要圖並通過某些系統命令顯示。或者您可以嘗試其他GUI後端,如Tkgg,Wxagg。 – HYRY 2012-07-27 12:35:51

+0

我測試過的所有交互式後端結果都出現了相同的錯誤,所以我想它們不是一個選項。我將嘗試按照您的建議使用系統命令顯示圖形。 – 2012-07-27 12:56:50

0

我不能複製你的問題(部分原因是因爲你的例子不是自包含的),但我認爲你可以看看去着手解決這個問題略有不同。

因爲你的身材定義(大小,DPI等)保持整個迴路相同的(即使它沒有),你可以看一下生產只是一個數字,並更新其在循環中:

import matplotlib as mpl 
mpl.use("tkagg") 

from matplotlib import pyplot as plt 
import numpy as np 


file_number = 1000 
fig = plt.figure('abc', figsize=(22,12), dpi=100) 

plt.show(block=False) 

for num in np.arange(file_number): 
    fig.set_label('abc%s' % num) 

    # add an axes to the figure 
    ax = plt.axes() 

    #some plots are added to the figure (I just plotted a line) 
    plt.plot(range(num)) 

    plt.savefig("%d.png" % num, dpi=100) 
    # draw the latest changes to the gui 
    plt.draw() 

    # remove the axes now that we have done what we want with it. 
    fig.delaxes(ax) 

# put in a blocking show to wait for user interaction/closure. 
plt.show() 

通常,這是不是你會怎麼做的事情(我通常會更新軸,而不是添加/刪除每次一個),但也許你有一個很好的理由做這種方式。

這應該顯著提高性能。

+0

我首先嚐試了一種類似的方法,在循環之前構建一個數字,並使用.clf()清除其內容。然而,我遇到了一些主要問題(保存的圖像的大小以某種方式波動,或新的圖被添加到舊的而不是替換它們)。我真的不知道這個東西是如何工作的,但我想它與我在圖中添加的圖中使用的subplot2grid發生衝突。 – 2012-07-30 14:38:22

+0

我得到了這樣的錯誤: 'fig.delaxes(AX) 文件 「/usr/lib/pymodules/python2.7/matplotlib/figure.py」,線路619,在delaxes self._axstack.remove(一) 文件「/usr/lib/pymodules/python2.7/matplotlib/figure.py」,第76行,刪除 Stack.remove(self,self._entry_from_axes(a))文件「/ usr/lib/pymodules/(self._elements]中的[k,(ind,a))中的[(a,(ind,k))]中的[python2.7/matplotlib/figure.py],第72行,in_entry_from_axes ind,k = dict ] KeyError:' – 2012-07-30 14:42:23