time taken to savefig

Hi

I have been doing some work that generates a lot of plots and since the plots were taking a long time I looked into to whether I could speed up the process.

I found some information on how I might improve things from the following link:
http://stackoverflow.com/questions/11688318/how-to-speed-up-matplotlib-when-plotting-and-saving-lots-of-figures which showa that you can speed things up by using the same axes and simply updating the line data.

When I adapted this idea to my plots I noticed that, though the plot loop was quicker my script was running slower. I wrote a code snippet to repeat the problem - shown below:
#!/usr/bin/env python
import os, matplotlib, time
matplotlib.use(‘TkAgg’)
import matplotlib.pyplot as plt
import numpy as np
from cmpactionresultsbetweenviews_1 import getPlotHtml

allActionPlotLists = [[0, 1, 2 , 3, 4, 5, 6, 7, 8, 9],
[ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[9,8,7,6,5,4,3,2,1,0],
[19,18,17,16,15,14,13,12,11,10]]
allActionLegendsLists = [str(i) for i in range(len(allActionPlotLists[0]))]

legendProps={‘labelspacing’:0.5, ‘prop’:{‘size’:8}}
colours=[‘b±’, ‘r±’, ‘g±’, ‘k±’, ‘c±’, ‘m±’, ‘bD:’, ‘rD:’, ‘gD:’, ‘kD:’]
fig = plt.figure()
ax = None
plotlines = [None for i in range(len(allActionPlotLists))]
savedir = “tmpRes”
if not os.path.exists(savedir):
os.makedirs(savedir)
figSrcFnRoot = “plotFil”
fil = open(os.path.join(savedir, “savepng.html”), ‘w’)

xlabel = “x label”
ylabel = “values”
colours=[‘b±’, ‘r±’, ‘g±’, ‘k±’, ‘c±’, ‘m±’, ‘bD:’, ‘rD:’, ‘gD:’, ‘kD:’]

for i in range(20):
start_plot_time = time.time()
plottitle = “Plot %d” % (i)
fig.suptitle("")
fig.suptitle(plottitle)

for subPltIdx in range(len(allActionPlotLists)):
    li = allActionPlotLists[subPltIdx]
    if ax == None:
        ax = fig.add_subplot(1,1,1)
        ax.set_xlabel(xlabel)
        ax.set_ylabel(ylabel)
   
    if plotlines[subPltIdx] == None:
        ax.set_xlabel(xlabel)
        ax.set_ylabel(ylabel)
        plotlines[subPltIdx] = ax.plot(range(len(li)), li, colours[subPltIdx])[0]
    else:
        plotlines[subPltIdx].set_ydata(li)
        plotlines[subPltIdx].set_xdata(range(len(li)))

fig.legend(plotlines, allActionLegendsLists, labelspacing=0.5, prop=legendProps['prop'])
# **** change the above line for the one below and the increasing save time problem goes away
#ax.legend(plotlines, allActionLegendsLists, labelspacing=0.5, prop=legendProps['prop'])
print "plot Execution time:", time.time()-start_plot_time

figfn = "%s_%d" % (figSrcFnRoot, i)
figfnlink = figfn.replace('%', '%25').replace(';','%3b').replace(':','%3A')
fn = os.path.join(savedir, "%s.png" % figfn)
start_time = time.time()
fig.savefig(fn, format='png',dpi=75)
print "savefig Execution time:", time.time()-start_time
htmlStr = ''
htmlStr += '<center><img src="%s" alt="could not find %s image"/></center>' % (os.path.join(".","%s.png" % figfnlink), figfn)
fil.write(htmlStr + "<br>")

plt.close()
fil.close()

A little further investigation showed that savefig was taking longer each run of the loop. I eventually noticed that replacing the call to fig.legend() with ax.legend() solved the problem. Anyone know why the time taken to save the plot increases when using fig.legend() in the code above ?

While doing this I also noticed a couple of other things:

  1. I cannot seem to clear the figure title, so when I re-set it I get the new title overlaying the old one in the plot output. Does anyone know how to completely clear and reset the title of an existing figure ?

  2. The call to figure.legend() puts the legends nicely outside the plot boundaries (in the top right hand corner). The equivalent call to ax.legend() places the legends inside the plot boundary. Does anyone know a) why the behavior here is slightly different and b) how I can get the legends outside the plot boundary using ax.legend() ?