It seems that the standard way of creating a figure in matplotlib doesn't behave as I'd expect in python: by default calling fig = matplotlib.figure()
in a loop will hold on to all the figures created, and eventually run out of memory.
There are quite a few posts which deal with workarounds, but requiring explicit calls to matplotlib.pyplot.close(fig)
seems a bit hackish. What I'd like is a simple way to make fig
reference counted, so I won't have to worry about memory leaks. Is there some way to do this?
If you create the figure without using plt.figure
, then it should be reference counted as you expect. For example (This is using the non-interactive Agg backend, as well.)
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
# The pylab figure manager will be bypassed in this instance.
# This means that `fig` will be garbage collected as you'd expect.
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
If you're only going to be saving figures rather than displaying them, you can use:
def savefig(*args, **kwargs):
plt.savefig(*args, **kwargs)
plt.close(plt.gcf())
This is arguably no less hacky, but whatever.
If you want to profit from the use of pyplot
and have the possibility to wrap the figure in a class of your own, you can use the __del__
method of your class to close the figure.
Something like:
import matplotlib.pyplot as plt
class MyFigure:
"""This is my class that just wraps a matplotlib figure"""
def __init__(self):
# Get a new figure using pyplot
self.figure = plt.figure()
def __del__(self):
# This object is getting deleted, close its figure
plt.close(self.figure)
Whenever the garbage collector decides to delete your figure because it is inaccessible, the matplotlib
figure will be closed.
However note that if someone has grabbed the figure (but not your wrapper) they might be annoyed that you closed it. It probably can be solved with some more thought or imposing some restrictions on usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With