I'm running a python program which replots a graph every few minutes, but every time it runs the memory it uses goes up a little bit, and soon the raspberry pi I'm using slows to a crawl.
Here's the relevant piece of code:
import matplotlib.pyplot as plt
import matplotlib.dates as md
from memory_profiler import profile
@profile
def plotter(file_name, plot_name):
with open(filen_name, 'r') as readings:
reader = csv.reader(readings, delimiter=',')
data = [row for row in reader]
plt.plot(data[2], data[0])
ax = gca()
xfmt = md.DateFormatter('%H:%M') # xaxis is datetimes
ax.xaxis.set_major_formatter(xfmt)
plt.legend()
plt.savefig(plot_name, transparent=True)
plt.clf()
plt.cla()
plt.close()
And the function is called with something like:
while True:
plotter(file_name, plot_name)
sleep(100)
The memory_profiler spits out nice output, but it always looks like this:
Line # Mem usage Increment Line Contents
================================================
38 36.2 MiB 0.6 MiB plt.savefig(plot_name, transparent=True)
39 36.2 MiB 0.0 MiB plt.clf()
40 36.2 MiB 0.0 MiB plt.cla()
41 36.2 MiB 0.0 MiB plt.close()
(The rest of the function doesn't increase memory usage.)
The memory is incrementing up at savefig()
, but is never released despite the various ways I've tried to close the figure.
Anyone know why the close()
doesn't release the memory?
Edit:
I've tried another method.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot( some arguments)
fig.savefig(filename)
plt.close('all')
del ax, fig
This doesn't decrement the memory usage either.
Edit 2:
From this answer elsewhere (Create a figure that is reference counted) I've tried the following:
from matplotlib.backends.backend_svg import FigureCanvas
from matplotlib.figure import Figure
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot etc...
fig.savefig(file_name)
plt.close('all')
This also doesn't seem to work. Memory still increasing monotonically and always at the savefig
line of the function.
Save this question. Show activity on this post. It will create the figure the first time the code is run.
The last, Agg, is a non-interactive backend that can only write to files. It is used on Linux, if Matplotlib cannot connect to either an X display or a Wayland display.
I encountered the same issue. After looking around I found a solution: you need to close the fig AND all windows.
import matplotlib.pylab as plt
fig,ax = plt.subplots(1)
plt.plot(X, Y)
fig.savefig(img_name)
fig.clf()
plt.close()
After closing both the plot and figure, my memory stayed at a more or less constant level.
You can also close the axis using:
ax.cla()
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