Memory usage when plotting sequental figures

Hi,

if I use something like this:

···

==================================================
import numpy as np
import matplotlib.pyplot as plt

def draw_fig(arr, fn):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.contourf(arr)
    plt.savefig(fn)

if __name__ == '__main__':
  for i in range(10):
    draw_fig(np.random.random((10, 10)), 'fig_%02d.png' % i)

memory usage grows with every loop, so I can't plot this way many sequences.

I know there is animation class in Matplotlib, but this way is easier to me, and I think I miss something fundamental because this is happening. How can I avoid memory leak using this approach?

Thanks

Hi,

if I use something like this:

==================================================
import numpy as np
import matplotlib.pyplot as plt

def draw_fig(arr, fn):
     fig = plt.figure()
     ax = fig.add_subplot(111)
     ax.contourf(arr)
     plt.savefig(fn)

        plt.close(fig) # that should take care of it

···

On 2013/05/27 9:51 PM, zetah wrote:

if __name__ == '__main__':
  for i in range(10):
    draw_fig(np.random.random((10, 10)), 'fig_%02d.png' % i)

memory usage grows with every loop, so I can't plot this way many sequences.

I know there is animation class in Matplotlib, but this way is easier to me, and I think I miss something fundamental because this is happening. How can I avoid memory leak using this approach?

Thanks

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Eric Firing wrote:

       plt.close(fig) # that should take care of it

Thanks for your quick reply.

I tried before posting `plt.close()` and it didn't work, but also `plt.close(fig)` doesn't change memory pumping with every loop.
BTW, I'm on Windows with Matplotlib 1.2.1

"zetah" wrote:

Eric Firing wrote:

       plt.close(fig) # that should take care of it

Thanks for your quick reply.

I tried before posting `plt.close()` and it didn't work, but also
`plt.close(fig)` doesn't change memory pumping with every loop.
BTW, I'm on Windows with Matplotlib 1.2.1

I solved the problem by using animation class. If was a bit tricky, as I had inner loops that also were producing plots for same sequence, and from what I understood about this class, iterator is "frames" argument in FuncAnimation() function, which also returns the frame, so you may imagine how I solved inner loops.
I guess there is instrumentation for such case, but documentation about animation class is beyond my comprehension. Also couple of blogs explaining basics of FuncAnimation() function weren't very helpful to me. Maybe it's my limitation...

Anyway, I'm still curious how to close figure from my initial message, so that memory won't leak. I welcome your replies

I had this problem as well. I think my solution was to tell the garbage collector to collect.

import gc

import numpy as np

import matplotlib.pyplot as plt

def draw_fig(arr, fn):

fig = plt.figure()
ax = fig.add_subplot(111)

ax.contourf(arr)
plt.savefig(fn)

plt.close(fig)

gc.collect()

I tried to test this with Python3.3, but didn’t have any issues with memory increasing when using ‘plt.close’.

···

On Tue, May 28, 2013 at 8:04 AM, zetah <otrov@…4366…> wrote:

“zetah” wrote:

Eric Firing wrote:

   plt.close(fig)  # that should take care of it

Thanks for your quick reply.

I tried before posting plt.close() and it didn’t work, but also

plt.close(fig) doesn’t change memory pumping with every loop.

BTW, I’m on Windows with Matplotlib 1.2.1

I solved the problem by using animation class. If was a bit tricky, as I had inner loops that also were producing plots for same sequence, and from what I understood about this class, iterator is “frames” argument in FuncAnimation() function, which also returns the frame, so you may imagine how I solved inner loops.

I guess there is instrumentation for such case, but documentation about animation class is beyond my comprehension. Also couple of blogs explaining basics of FuncAnimation() function weren’t very helpful to me. Maybe it’s my limitation…

Anyway, I’m still curious how to close figure from my initial message, so that memory won’t leak. I welcome your replies


Try New Relic Now & We’ll Send You this Cool Shirt

New Relic is the only SaaS-based application performance monitoring service

that delivers powerful full stack analytics. Optimize and monitor your

browser, app, & servers with just a few lines of code. Try New Relic

and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Albert Kottke wrote:

I had this problem as well. I think my solution was to tell the
garbage collector to collect.

import gc
import numpy as np
import matplotlib.pyplot as plt

def draw_fig(arr, fn):
   fig = plt.figure()
   ax = fig.add_subplot(111)
   ax.contourf(arr)
   plt.savefig(fn)
   plt.close(fig)
   gc.collect()

I tried to test this with Python3.3, but didn't have any issues
with memory increasing when using 'plt.close'.

Thanks Albert, that indeed does the trick :slight_smile:

If I understand your last sentence, you are saying garbage collector intervention isn't needed for Python 3.3.

Cheers

Correct.

···

On Tue, May 28, 2013 at 9:42 AM, zetah <otrov@…4367…66…> wrote:

Albert Kottke wrote:

I had this problem as well. I think my solution was to tell the

garbage collector to collect.

import gc

import numpy as np

import matplotlib.pyplot as plt

def draw_fig(arr, fn):

fig = plt.figure()

ax = fig.add_subplot(111)

ax.contourf(arr)

plt.savefig(fn)

plt.close(fig)

gc.collect()

I tried to test this with Python3.3, but didn’t have any issues

with memory increasing when using ‘plt.close’.

Thanks Albert, that indeed does the trick :slight_smile:

If I understand your last sentence, you are saying garbage collector intervention isn’t needed for Python 3.3.

Cheers