matplotlib畫圖:當循環生成的圖過多時,會提示內存不夠等或與內存相關的error提示

總會要畫大量的圖,我是在一個for中循環畫圖,每當畫到第250張到300張左右,總遇到提示說內存不夠了或者直接Spyder死掉崩掉這樣的情況。一開始也很無奈,看到有的帖子說,要將32位的python換到64位,其實也還是沒有解決根本問題。

 

第一種解法:

figure 的重複利用能大大節約時間,但是 matplotlib 維護的 figure 有數量上限。並且,不斷的創建新的 figure 實例,很容易造成內存泄漏,而應合理的複用,能大大的提高運行速度。
 

問題還是要解決的,終於找到了比較可行的方法,如下幾種:

import matplotlib.pylot as plt

  1. plt.cla() # Clear axis即清除當前圖形中的當前活動軸。其他軸不受影響。

  2. plt.clf() # Clear figure清除所有軸,但是窗口打開,這樣它可以被重複使用。

  3. plt.close() # Close a figure window,如果未另指定,則該窗口將是當前窗口

官網有這樣的描述

You can clear the current figure with clf() and the current axes with cla(). If you find this statefulness, annoying, don’t despair, this is just a thin stateful wrapper around an object oriented API, which you can use instead (see Artist tutorial)

If you are making a long sequence of figures, you need to be aware of one more thing: the memory required for a figure is not completely released until the figure is explicitly closed with close(). Deleting all references to the figure, and/or using the window manager to kill the window in which the figure appears on the screen, is not enough, because pyplot maintains internal references until close() is called.

 

1. plt.cla() # 清除axes,即當前 figure 中的活動的axes,但其他axes保持不變。

from matplotlib import pyplot

while True:
  fig = pyplot.figure()
  ax = fig.add_subplot(111)
  ax.plot(x,y)
  ax.legend(legendStrings, loc = 'best')
  fig.savefig('himom.png')
  # etc....
  pyplot.cla()

能看到上述代碼的循環最後一句,添加了 pyplot.cla()。

或者替換成close(fig)。

這個close(fig)函數還允許指定應關閉哪個窗口。參數可以是在創建窗口時使用的數字或名稱。figure(number_or_name)或者它可以是一個圖形實例fig獲得,即使用fig= figure()..如果沒有給出任何論據close(),當前活動的窗口將關閉。

 

三中語法到底最佳應用場景,目前還不那麼特別明白。之後有進一步的發現,我會更新到這裏

看到一個朋友提供的實例,我引用到這裏:

我今天發現的只是一個警告。 如果有一個函數調用一個劇情很多次,你最好使用plt.close(fig)而不是fig.clf(),第一個不會在內存中累積。 總之,如果內存是一個問題,請使用plt.close(fig)(雖然看起來有更好的方法,但是對於相關的鏈接請看這個評論的結尾)。

因此,下面的腳本會產生一個空的列表:

for i in range(5):
    fig = plot_figure()
    plt.close(fig)
# This returns a list with all figure numbers available
print(plt.get_fignums())

而這一張則會列出五位數的名單。

for i in range(5):
    fig = plot_figure()
    fig.clf()
# This returns a list with all figure numbers available
print(plt.get_fignums())

從上面的文檔我不清楚什麼是關閉一個數字和關閉一個窗口之間的區別。 也許這些代碼會讓你搞清楚。

如果想嘗試一個完整的腳本,可以:

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1000)
y = np.sin(x)

for i in range(5):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, y)
    plt.close(fig)

print(plt.get_fignums())

for i in range(5):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, y)
    fig.clf()

print(plt.get_fignums())

第二種解法:

不要將繪出來的圖展示在anaconda 或者其他編譯器的console控制檯中。

在導入matplotlib庫後,且在matplotlib.pyplot庫被導入前加“matplotlib.use(‘agg')”語句。其實我在之後有試過,也可以達到效果。

?

1

2

3

4

5

6

import numpy as np

import matplotlib

matplotlib.use('agg')

 

import matplotlib.pyplot as plt  # matplotlib.use('agg')必須在本句執行前運行

(後續代碼略)

在Jupyter Notebook頁面內顯示繪圖

在使用Jupyter Notebook寫文檔時,如需在本頁面內顯示繪圖,只需加入“%matplotlib inline”語句。

?

1

2

3

4

import numpy as np

import pandas as pd

%matplotlib inline

(後續代碼略)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章