2

I am trying to write a python Code snippet which creates 24 figures and 9 subplot and saves them in the directory. Its taking around 197 sec to create all the 24 figures and save them. This is implemented Raspberry Pi 3. How could I optimize the code further to obtain a better Speed up?

import numpy
import matplotlib
matplotlib.use('Agg') #changed the backend
import time
import matplotlib.pyplot as plt

start_program = time.time()
for i in range(24):
    start = time.time()
    fig = plt.figure(num = i, figsize = (20, 10))
    string = 'Title of the graph ' + str(i)
    fig.suptitle(string, fontsize =20)

    for j in range(9):
        ax = fig.add_subplot(3,3,j+1)
        ax.cla()
        string = 'subgraph title' + str(j)
        ax.title.set_text(string)
        ax.axis([0,60,0,35])
        ax.grid(color = 'g', linestyle = '-', linewidth = 1)

    string = 'save_fig'
    string = string + str(i) +'.png'
    fig.savefig(string)
    print("Total time taken to save fig ",i, "is", time.time()-start)

end_program = time.time()
print("Total time to complete program is :", end_program - start_program)

And the output Looks like this

Total time taken to save fig 0 is 7.201676845550537(Worried about 7sec time to create a figure and save it)
Total time taken to save fig 1 is 7.540156602859497
Total time taken to save fig 2 is 9.28951120376587
Total time taken to save fig 3 is 7.745286464691162
Total time taken to save fig 4 is 9.9215247631073
Total time taken to save fig 5 is 8.051039695739746
Total time taken to save fig 6 is 8.413954019546509
Total time taken to save fig 7 is 8.299449920654297
Total time taken to save fig 8 is 8.348041296005249
Total time taken to save fig 9 is 9.227581977844238
Total time taken to save fig 10 is 11.946017026901245
Total time taken to save fig 11 is 7.378983020782471
Total time taken to save fig 12 is 7.357311010360718
Total time taken to save fig 13 is 8.607544660568237
Total time taken to save fig 14 is 7.370815992355347
Total time taken to save fig 15 is 7.3785529136657715
Total time taken to save fig 16 is 8.844587087631226
Total time taken to save fig 17 is 7.358648777008057
Total time taken to save fig 18 is 7.3571202754974365
Total time taken to save fig 19 is 7.349349737167358
Total time taken to save fig 20 is 9.172396898269653
Total time taken to save fig 21 is 7.359432935714722
Total time taken to save fig 22 is 7.376481533050537
Total time taken to save fig 23 is 7.487479209899902
Total time to complete program is : 197.89335536956787 

How can I reduce the total time?

  • I have exactly the same performance problem as described above. I also set up a non-interactive backend via 'Agg' and was surprised at how slow the code performed. I was able to isolate most of the problem to the "import matplotlib.pyplot as plt" statement which take approximately 55 seconds on my raspberry pi 2 model B i've not yet found a way to significantly speed this up – Cliff Nov 16 '17 at 2:32
2

You could try to use matplotlib without QT, i.e. with a non-interactive backend, if non-interactive plotting generating image files only is the goal. It will skip any overhead related to the GUI backends.

From matplotlib's FAQ:

There are two types of backends: user interface backends (for use in pygtk, wxpython, tkinter, qt4, or macosx; also referred to as “interactive backends”) and hardcopy backends to make image files (PNG, SVG, PDF, PS; also referred to as “non-interactive backends”).

[...]

Here is a summary of the matplotlib renderers (there is an eponymous backed for each; these are non-interactive backends, capable of writing to a file):

enter image description here Image source

import matplotlib 
# configure backend here
matplotlib.use('Agg')

Some other ideas to speed things up, taken from Speeding up Matplotlib and Speeding up Matplotlib plotting times for real-time monitoring purposes:

Re-use plots and do not create axes and text labels for each frame:

Instead of calling clear() and then plot(), thus effectively deleting everything about the plot, then re-creating it for every frame, we can keep an existing plot and only modify its data:

Re-draw only what's changed:

What we can do here is to selectively draw only the parts that are actually changing. That is, at least the background and the line. [...] Note that you have to add fig.canvas.update() to copy the newly rendered lines to the drawing backend.

Avoid rescaling of axes if possible:

One of the reasons that this is rather slow still is due to the fact that I am rescaling the axis each step -- redrawing axis is costly. If you set the axis limits to fixed number the speedup becomes amazing

  • Hello Ghanima, I have gone through the Content you have posted and used the backend as 'Agg' as you have suggested. But I was not able to obtain signifícant improvements in the Speed up. I have attached the Code snippet and the corresponding Output as an other answer in the same post. How could I optimize the Code further? Thank you in advance. – code_slack Sep 18 '17 at 10:32
  • I have re-edited the question. – code_slack Sep 20 '17 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.