matplotlib画图:当循环生成的图过多时,会提示内存不够等或与内存相关的error提示

当在Python中使用matplotlib进行循环画图时,可能会遇到内存不足的问题。本文介绍了两种解决方案:一是通过调用clf(), cla()或close()清理图形资源;二是设置matplotlib使用'agg'后端,避免在console中显示图像,从而减少内存占用。这两种方法能有效避免因大量画图导致的内存泄漏和程序崩溃。" 77658129,7218163,使用jQuery实现选项卡与弹出层效果,"['前端开发', 'jQuery', 'HTML', 'CSS', 'JavaScript']

总会要画大量的图,我是在一个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

(后续代码略)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值