In this code, there is a 4-D array of 13x13 images. I would like to save each 13x13 image using matplotlib.pyplot. Here for debugging purposes, I limit the outer loop to 1.
#fts is a numpy array of shape (4000,100,13,13)
no_images = 4000
for m in [1]:
for i in range(no_images):
print i,
fm = fts[i][m]
if fm.min() != fm.max():
fm -= fm.min()
fm /= fm.max() #scale to [0,1]
else:
print 'unscaled'
plt.imshow(fmap)
plt.savefig('m'+str(m)+'_i'+str(i)+'.png')
Saving 4000 images took more than 20 hours. Why is it this slow? If I limit the inner loop to the first 100 images, it takes about 1 minute. So the whole thing should be completed in 40 minutes, not over 20 hours! And I notice it seems to run progressively slower.
Java can 'sort of' run the instructions in your for loop in parallel with itself. Python has no concrete types and so the nature of the work to be done has to be decided at every instruction. This causes your entire computer to stop and wait for all the memory in all of your variables to be re-scanned.
Originally Answered: Why are for loops so slow in Matlab? The loops incur much overhead of MATLAB, the interpreted language, calling many compiled code routines. It calls the compiled code routines each time it re-enters the body of the loop.
A faster way to loop using built-in functions A faster way to loop in Python is using built-in functions. In our example, we could replace the for loop with the sum function. This function will sum the values inside the range of numbers. The code above takes 0.84 seconds.
If your Python code runs too fast, a call to time. sleep() is a simple way to slow down your code.
What you experience here is a memory leak: you keep creating instances of AxesImage
objects (by repetitively calling plt.imshow
) to the moment they can't fit into RAM; and then the whole thing begins swapping to disk, which is incredibly slow. To avoid memory leaks, you can either destroy AxesImage
instance when you don't need it:
...
image = plt.imshow(fmap)
plt.savefig('m'+str(m)+'_i'+str(i)+'.png')
del(image)
Or, alternatively, you can create only one AxesImage
, and then just change the data in it:
...
image = None
for m in [1]:
for i in range(no_images):
...
if image is None:
image = plt.imshow(fmap)
else:
image.set_data(fmap)
...
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