Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib runs out of memory when plotting in a loop

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') 

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:\phdproject\alexander paper\python\v3\plotcolumns.py", line 48, in plo tColumns     savefig(filenamePrefix+dtAsString+'.png', dpi=300)   File "C:\Python25\lib\site-packages\matplotlib\pyplot.py", line 356, in savefi g     return fig.savefig(*args, **kwargs)   File "C:\Python25\lib\site-packages\matplotlib\figure.py", line 1032, in savef ig     self.canvas.print_figure(*args, **kwargs)   File "C:\Python25\lib\site-packages\matplotlib\backend_bases.py", line 1476, i n print_figure     **kwargs)   File "C:\Python25\lib\site-packages\matplotlib\backends\backend_agg.py", line 358, in print_png     FigureCanvasAgg.draw(self)   File "C:\Python25\lib\site-packages\matplotlib\backends\backend_agg.py", line 314, in draw     self.figure.draw(self.renderer)   File "C:\Python25\lib\site-packages\matplotlib\artist.py", line 46, in draw_wr apper     draw(artist, renderer, *kl)   File "C:\Python25\lib\site-packages\matplotlib\figure.py", line 773, in draw     for a in self.axes: a.draw(renderer)   File "C:\Python25\lib\site-packages\matplotlib\artist.py", line 46, in draw_wr apper     draw(artist, renderer, *kl)   File "C:\Python25\lib\site-packages\matplotlib\axes.py", line 1735, in draw     a.draw(renderer)   File "C:\Python25\lib\site-packages\matplotlib\artist.py", line 46, in draw_wr apper     draw(artist, renderer, *kl)   File "C:\Python25\lib\site-packages\matplotlib\legend.py", line 374, in draw     bbox = self._legend_box.get_window_extent(renderer)   File "C:\Python25\lib\site-packages\matplotlib\offsetbox.py", line 209, in get _window_extent     px, py = self.get_offset(w, h, xd, yd)   File "C:\Python25\lib\site-packages\matplotlib\offsetbox.py", line 162, in get _offset     return self._offset(width, height, xdescent, ydescent)   File "C:\Python25\lib\site-packages\matplotlib\legend.py", line 360, in findof fset     return _findoffset(width, height, xdescent, ydescent, renderer)   File "C:\Python25\lib\site-packages\matplotlib\legend.py", line 325, in _findo ffset_best     ox, oy = self._find_best_position(width, height, renderer)   File "C:\Python25\lib\site-packages\matplotlib\legend.py", line 817, in _find_ best_position     verts, bboxes, lines = self._auto_legend_data()   File "C:\Python25\lib\site-packages\matplotlib\legend.py", line 669, in _auto_ legend_data     tpath = trans.transform_path(path)   File "C:\Python25\lib\site-packages\matplotlib\transforms.py", line 1911, in t ransform_path     self._a.transform_path(path))   File "C:\Python25\lib\site-packages\matplotlib\transforms.py", line 1122, in t ransform_path     return Path(self.transform(path.vertices), path.codes,   File "C:\Python25\lib\site-packages\matplotlib\transforms.py", line 1402, in t ransform     return affine_transform(points, mtx) MemoryError: Could not allocate memory for path 

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.

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

like image 970
Chinmay Kanchi Avatar asked Mar 02 '10 16:03

Chinmay Kanchi


People also ask

What happens if I dont use %Matplotlib inline?

In the current versions of the IPython notebook and jupyter notebook, it is not necessary to use the %matplotlib inline function. As, whether you call matplotlib. pyplot. show() function or not, the graph output will be displayed in any case.

Is Pyqtgraph faster than matplotlib?

matplotlib: For plotting, pyqtgraph is not nearly as complete/mature as matplotlib, but runs much faster.

Does matplotlib work in idle?

Download the “Install Matplotlib (for Mac)” file from my web site, and double-click it to run it. Test your installation. Start IDLE, type “import matplotlib”, and confirm that this command completes without an error.


2 Answers

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()

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.... 
like image 126
Mark Avatar answered Oct 10 '22 22:10

Mark


I've also run into this error. what seems to have fixed it is

while True:     fig = pyplot.figure()     ax = fig.add_subplot(111)     ax.plot(x,y)     ax.legend(legendStrings, loc = 'best')     fig.savefig('himom.png')     #new bit here     pylab.close(fig) #where f is the figure 

running my loop stably now with fluctuating memory but no consistant increase

like image 35
ninjasmith Avatar answered Oct 10 '22 21:10

ninjasmith