6

I am plotting and saving thousands of files for later animation in a loop like so:

import matplotlib.pyplot as plt
for result in results:
    plt.figure()
    plt.plot(result)                     # this changes
    plt.xlabel('xlabel')                 # this doesn't change
    plt.ylabel('ylabel')                 # this doesn't change
    plt.title('title')                   # this changes
    plt.ylim([0,1])                      # this doesn't change
    plt.grid(True)                       # this doesn't change
    plt.savefig(location, bbox_inches=0) # this changes

When I run this with a lot of results, it crashes after several thousand plots are saved. I think what I want to do is reuse my axes like in this answer: https://stackoverflow.com/a/11688881/354979 but I don't understand how. How can I optimize it?

Community
  • 1
  • 1
rhombidodecahedron
  • 7,693
  • 11
  • 58
  • 91
  • 1
    I ran into a similar issue like this a few weeks ago. I solved my problem my creating the plots in sub-groups, saving them to disk, clearing it from my memory, and then going on to plot the rest. I think its from inefficiencies in the way matplotlib holds plots in memory when dealing with large or many plots. Unfortunately one of the assumptions the library is that the data used should be *relatively* small. My plotting worked fine as long as I could hold the plots in memory and not swap out to disc. – agconti Aug 13 '13 at 16:26
  • 5
    add a `plt.close('all')` at the end of your loop. It won't make it faster, but it will keep you from running out of memory. – tacaswell Aug 13 '13 at 16:51
  • @tcaswell thanks for the tip! I wasn't aware of the `plt.close('all')` method. – agconti Aug 13 '13 at 18:58

2 Answers2

5

I would create a single figure and clear the figure each time (use .clf).

import matplotlib.pyplot as plt

fig = plt.figure()

for result in results:
    fig.clf()   # Clears the current figure
    ...

You are running out of memory since each call to plt.figure creates a new figure object. Per @tcaswell's comment, I think this would be faster than .close. The differences are explained in:

When to use cla(), clf() or close() for clearing a plot in matplotlib?

Community
  • 1
  • 1
Hooked
  • 84,485
  • 43
  • 192
  • 261
  • Is there any difference between 'fig=plt.figure(); for result in results: fig.clf()...' and 'plt.figure(); for result in results: plt.clf()...'? – rhombidodecahedron Aug 13 '13 at 18:11
  • 1
    @EarlBellinger There is no difference when you only have a single figure. `plt.figure().clf` calls the current figure while `fig.clf` calls a named object representing our figure. If we had multiple figures these could be different. – Hooked Aug 13 '13 at 18:42
2

Although this question is old, the answer would be:

import matplotlib.pyplot as plt
fig = plt.figure()
plot = plt.plot(results[0])
title = plt.title('title')

plt.xlabel('xlabel')
plt.ylabel('ylabel')
plt.ylim([0,1])
plt.grid(True)

for i in range(1,len(results)):
    plot.set_data(results[i])
    title.set_text('new title')
    plt.savefig(location[i], bbox_inches=0)
plt.close('all')
Renatius
  • 542
  • 1
  • 3
  • 11