Matplotlib 在循环绘图时内存不足 [英] Matplotlib runs out of memory when plotting in a loop

查看:83
本文介绍了Matplotlib 在循环绘图时内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当简单的绘图程序,如下所示:

I have a fairly simple plotting routine that looks like this:

from __future__ import division
import datetime
import matplotlib
matplotlib.use('Agg')
from matplotlib.pyplot import figure, plot, show, legend, close, savefig, rcParams
import numpy
from globalconstants import *

    def plotColumns(columnNumbers, t, out, showFig=False, filenamePrefix=None, saveFig=True, saveThumb=True):
        lineProps = ['b', 'r', 'g', 'c', 'm', 'y', 'k', 'b--', 'r--', 'g--', 'c--', 'm--', 'y--', 'k--', 'g--', 'b.-', 'r.-', 'g.-', 'c.-', 'm.-', 'y.-', 'k.-']

        rcParams['figure.figsize'] = (13,11)
        for i in columnNumbers:
            plot(t, out[:,i], lineProps[i])

        legendStrings = list(numpy.zeros(NUMCOMPONENTS)) 
        legendStrings[GLUCOSE] = 'GLUCOSE'
        legendStrings[CELLULOSE] = 'CELLULOSE'
        legendStrings[STARCH] = 'STARCH'
        legendStrings[ACETATE] = 'ACETATE'
        legendStrings[BUTYRATE] = 'BUTYRATE'
        legendStrings[SUCCINATE] = 'SUCCINATE'
        legendStrings[HYDROGEN] = 'HYDROGEN'
        legendStrings[PROPIONATE] = 'PROPIONATE'
        legendStrings[METHANE] = "METHANE"

        legendStrings[RUMINOCOCCUS] = 'RUMINOCOCCUS'
        legendStrings[METHANOBACTERIUM] = "METHANOBACTERIUM"
        legendStrings[BACTEROIDES] = 'BACTEROIDES'
        legendStrings[SELENOMONAS] = 'SELENOMONAS'
        legendStrings[CLOSTRIDIUM] = 'CLOSTRIDIUM'

        legendStrings = [legendStrings[i] for i in columnNumbers]
        legend(legendStrings, loc='best')

        dt = datetime.datetime.now()
        dtAsString = dt.strftime('%d-%m-%Y_%H-%M-%S')

        if filenamePrefix is None:
            filenamePrefix = ''

        if filenamePrefix != '' and filenamePrefix[-1] != '_':
            filenamePrefix += '_'

        if saveFig: 
            savefig(filenamePrefix+dtAsString+'.eps')

        if saveThumb:
            savefig(filenamePrefix+dtAsString+'.png', dpi=300)


        if showFig: f.show()

        close('all')

当我在单次迭代中绘制它时,它工作正常.然而,当我把它放在一个循环中的那一刻,matplotlib 发出嘶嘶声......

When I plot this in single iterations, it works fine. However, the moment I put it in a loop, matplotlib throws a hissy fit...

Traceback (most recent call last):
  File "c4hm_param_variation_h2_conc.py", line 148, in <module>
    plotColumns(columnNumbers, timeVector, out, showFig=False, filenamePrefix='c
4hm_param_variation_h2_conc_'+str(hydrogen_conc), saveFig=False, saveThumb=True)

  File "D:phdprojectalexander paperpythonv3plotcolumns.py", line 48, in plo
tColumns
    savefig(filenamePrefix+dtAsString+'.png', dpi=300)
  File "C:Python25libsite-packagesmatplotlibpyplot.py", line 356, in savefi
g
    return fig.savefig(*args, **kwargs)
  File "C:Python25libsite-packagesmatplotlibfigure.py", line 1032, in savef
ig
    self.canvas.print_figure(*args, **kwargs)
  File "C:Python25libsite-packagesmatplotlibackend_bases.py", line 1476, i
n print_figure
    **kwargs)
  File "C:Python25libsite-packagesmatplotlibackendsackend_agg.py", line
358, in print_png
    FigureCanvasAgg.draw(self)
  File "C:Python25libsite-packagesmatplotlibackendsackend_agg.py", line
314, in draw
    self.figure.draw(self.renderer)
  File "C:Python25libsite-packagesmatplotlibartist.py", line 46, in draw_wr
apper
    draw(artist, renderer, *kl)
  File "C:Python25libsite-packagesmatplotlibfigure.py", line 773, in draw
    for a in self.axes: a.draw(renderer)
  File "C:Python25libsite-packagesmatplotlibartist.py", line 46, in draw_wr
apper
    draw(artist, renderer, *kl)
  File "C:Python25libsite-packagesmatplotlibaxes.py", line 1735, in draw
    a.draw(renderer)
  File "C:Python25libsite-packagesmatplotlibartist.py", line 46, in draw_wr
apper
    draw(artist, renderer, *kl)
  File "C:Python25libsite-packagesmatplotliblegend.py", line 374, in draw
    bbox = self._legend_box.get_window_extent(renderer)
  File "C:Python25libsite-packagesmatplotliboffsetbox.py", line 209, in get
_window_extent
    px, py = self.get_offset(w, h, xd, yd)
  File "C:Python25libsite-packagesmatplotliboffsetbox.py", line 162, in get
_offset
    return self._offset(width, height, xdescent, ydescent)
  File "C:Python25libsite-packagesmatplotliblegend.py", line 360, in findof
fset
    return _findoffset(width, height, xdescent, ydescent, renderer)
  File "C:Python25libsite-packagesmatplotliblegend.py", line 325, in _findo
ffset_best
    ox, oy = self._find_best_position(width, height, renderer)
  File "C:Python25libsite-packagesmatplotliblegend.py", line 817, in _find_
best_position
    verts, bboxes, lines = self._auto_legend_data()
  File "C:Python25libsite-packagesmatplotliblegend.py", line 669, in _auto_
legend_data
    tpath = trans.transform_path(path)
  File "C:Python25libsite-packagesmatplotlib	ransforms.py", line 1911, in t
ransform_path
    self._a.transform_path(path))
  File "C:Python25libsite-packagesmatplotlib	ransforms.py", line 1122, in t
ransform_path
    return Path(self.transform(path.vertices), path.codes,
  File "C:Python25libsite-packagesmatplotlib	ransforms.py", line 1402, in t
ransform
    return affine_transform(points, mtx)
MemoryError: Could not allocate memory for path

这发生在第 2 次迭代(从 1 开始计数),如果这有所不同的话.代码在 32 位 Windows XP 上运行,使用 python 2.5 和 matplotlib 0.99.1、numpy 1.3.0 和 scipy 0.7.1.

This happens on iteration 2 (counting from 1), if that makes a difference. The code is running on Windows XP 32-bit with python 2.5 and matplotlib 0.99.1, numpy 1.3.0 and scipy 0.7.1.

代码现已更新,以反映崩溃实际发生在调用 legend() 的事实.评论呼叫解决了问题,但显然,我仍然希望能够在我的图表上添加图例......

The code has now been updated to reflect the fact that the crash actually occurs at the call to legend(). Commenting that call out solves the problem, though obviously, I would still like to be able to put a legend on my graphs...

推荐答案

每个循环是否应该生成一个新图形?我没有看到您关闭它或从循环到循环创建新的图形实例.

Is each loop supposed to generate a new figure? I don't see you closing it or creating a new figure instance from loop to loop.

在循环结束时保存当前图形后,此调用将清除当前图形:

This call will clear the current figure after you save it at the end of the loop:

pyplot.clf()

pyplot.clf()

不过,我会重构,让您的代码更加面向对象,并在每个循环中创建一个新的图形实例:

I'd refactor, though, and make your code more OO and create a new figure instance on each loop:

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....

这篇关于Matplotlib 在循环绘图时内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆