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: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-packagesmatplotlibbackend_bases.py", line 1476, i n print_figure **kwargs) File "C:Python25libsite-packagesmatplotlibbackendsbackend_agg.py", line 358, in print_png FigureCanvasAgg.draw(self) File "C:Python25libsite-packagesmatplotlibbackendsbackend_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-packagesmatplotlibtransforms.py", line 1911, in t ransform_path self._a.transform_path(path)) File "C:Python25libsite-packagesmatplotlibtransforms.py", line 1122, in t ransform_path return Path(self.transform(path.vertices), path.codes, File "C:Python25libsite-packagesmatplotlibtransforms.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…
Advertisement
Answer
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....