Reputation: 1039
I have identified a memory leak in matplotlib.imshow. I am aware of similar questions (like Excessive memory usage in Matplotlib imshow) and I've read the related ironpython thread (https://github.com/ipython/ipython/issues/1623/).
I believe that the code below should (in the absence of a memory leak) consume a constant amount of memory while running. Instead, it grows with each iteration.
I'm running the most recent version I can find (matplotlib-1.2.0rc3.win32-py2.7 and numpy-1.7.0.win32-py2.7), and the problem remains. I'm not keeping the return value of imshow, and in fact I'm explicitly deleting it, so I think the note in IronPython discussion doesn't apply. The behavior is identical with and without the explicit assignment-and-del inside the loop.
I see the same behavior with matplotlib-1.2.0.win32-py2.7.
Each iteration seems to hang onto whatever memory was needed for the image. I've chosen a large (1024x1024) random matrix to make the size of each image interestingly large.
I'm running Win7 pro with 2G of physical RAM, 32-bit python2.7.3 (hence the memory error), and the above numpy and matplotlib packages. The code below fails with a memory error in iteration 440 or so. The windows task manager reports consumption of 1,860,232K when it fails.
Here is code that demonstrates the leak:
IMAGE_SIZE = 1024
import random
RANDOM_MATRIX = []
for i in range(IMAGE_SIZE):
RANDOM_MATRIX.append([random.randint(0, 100) for each in range(IMAGE_SIZE)])
def exercise(aMatrix, aCount):
for i in range(aCount):
anImage = imshow(aMatrix, origin='lower left', vmin=0, vmax=100)
del(anImage)
if __name__=='__main__':
from pylab import *
exercise(RANDOM_MATRIX, 4096)
I can presumably render the image with PIL instead matplotlib. In the absence of a workaround, I do think this is a show-stopper for matplotlib.
Upvotes: 4
Views: 2638
Reputation: 1374
I struggled to make it work because many post talk about this problem, but no one seems to care about providing a working example.
first of all, you should never use the from ... import *
syntax, when using a library you didn't make yourself - because, you can never be sure it doesn't declare a symbol which would conflict with yours.
Then, calling set_data
is not sufficient to solve this problem - for three reasons :
flush_events()
by yourself.imshow()
with values it
can use to setup it's color map.Here is a working solution (link):
Upvotes: 1
Reputation: 1039
I think I found a workaround, I didn't fully realize how heavyweight imshow is.
The answer is to call imshow just once, then call set_data with RANDOM_MATRIX for each subsequent image.
Problem solved!
Upvotes: 1