1

I am trying to print a sequence of images in a code loop. I will ultimately need to print around 1000 to show how my system varies with time. I have reviewed the methods outlined in Matplotlib runs out of memory when plotting in a loop but I still can't make the code produce more than 96 images or so.

The code I am using in its stripped out form is below

import numpy as np
import matplotlib as mpl
import os
def pltHM(graphname,graphtext,xAxis,yAxis,xMn,xMx,xCnt,yMn,yMx,yCnt,TCrt):       
    plt = mpl.pyplot    
    fig = plt.figure(figsize=(8,7), dpi=250)
    cmap = mpl.cm.jet
    norm = mpl.colors.Normalize(vmin=-3, vmax=3)        
    X = np.linspace(xMn,xMx,xCnt)
    Y = np.linspace(yMn,yMx,yCnt)
    plt.xlabel(xAxis)
    plt.ylabel(yAxis)
    plt.pcolormesh(X,Y,TCrt,  cmap=cmap,norm=norm)
    plt.grid(color='w')
    plt.suptitle(graphtext, fontsize=14)
    plt.colorbar()
    plt.savefig(graphname, transparent = True)
    plt.cla()
    plt.clf()    
    plt.close(fig)
    del plt    
    del fig
    return

This is used in a simple loop as shown below

for loop1 in range(0,10):
    for loop2 in range(0,100):
        saveName = 'Test_Images/' + str(loop1) + '_' + str(loop2) + '.png'        
        plotHeatMap(saveName,'Test','X','Y',-35,35,141,-30,30,121,Z)

Any advice on why the above is not releasing memory and causing the traceback message

RuntimeError: Could not allocate memory for image

Many thanks for any help provided

Community
  • 1
  • 1
ultimatejo
  • 13
  • 3
  • 1
    Tip: You do not have to make a new figure in the loop. Make the figure *once*, then inside the loop *update* the plot and save it. Also, you are redefining pyplot every time. **Don't do that.** You only need it once, just do `import matplotlib.pyplot as plt` at the top, and get rid of the `plt = mpl.pyplot` funny business. – Ajean Aug 16 '16 at 15:48
  • Many thanks. I have now stripped that out and used pathoren's suggestion on the canvas drawing. Now working. Many thanks – ultimatejo Aug 17 '16 at 06:18

1 Answers1

2

Here is one stripped example of what you can do. As pointed out by Ajean, you should NOT import plt every time as you did! It is enough once. Also, do not delete the figure and create a new one...it is better to use the same figure and just replace the data.

import numpy as np
import matplotlib.pyplot as plt

def plotHeatMap(fig, line, x, y, graphname):  
    line.set_data(x, y)
    fig.canvas.draw()
    fig.savefig(graphname)

fig1, ax1 = plt.subplots(1, 1)
line, = ax1.plot([],[])
ax1.set_xlim(0, 1)
ax1.set_ylim(0, 1)
for loop1 in range(0, 2):
    for loop2 in range(0, 2):
        x = np.random.random(100)
        y = np.random.random(100)
        save_name = 'fig_'+str(loop1) + '_' + str(loop2) + '.png'
        plotHeatMap(fig1, line, x, y, save_name)
pathoren
  • 1,634
  • 2
  • 14
  • 22
  • Many thanks for the advise. Have set it up to redraw on the canvas and is now working. It is also now faster as well as completing. I really appreciate your help. – ultimatejo Aug 17 '16 at 06:17