1

I want to save figures plotted by a function that I don't want to have to touch (because it is an external function, and also because if tomorrow I don't want to save them and just display on the console, I don't want to have to edit the source code again and again). Is it possible to save the figures into a folder from ipython? Whether the figures are plotted in iPython or not is not a concern. I just want to be able to save them in a folder automatically, as they are a lot in number.

I have tried most of the solutions mentioned here, but they don't work - they just save a blank image file.

import matplotlib.pyplot as pl
fig = pl.figure()
external_function(parameters) # this function plots a figure
fig.savefig(r'path\to\folder\image.png') # saves a blank image.png into the folder
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
Kristada673
  • 3,512
  • 6
  • 39
  • 93
  • Adding a `save_figure=False` parameter to the function to decide whether to save it at the call site is not an option? The only alternative I could think would be to mock some object/library so that your external function will be tricked into using the `fig` you create instead of a new one, but how to do that depends on the code of `external_function` which you haven't provided. – Giacomo Alzetta Aug 03 '18 at 07:23
  • If I have to touch the source code, then its better to just do it as I show in the question, no? I mean, go to the line where the plotting is happening, and do the following: `fig = pl.figure() pl.plot(...) fig.savefig(r'path\to\folder\image.png')` – Kristada673 Aug 03 '18 at 07:25
  • You did not show anything in the question so I can only guess what you wanted to describe in the non-working code. Maybe you meant to write `external_function(fig, other_parameters)` to show that the function should accept an external figure definition, but if that's the cause your code failed to highlight that and instead showed you wanting to have said function magically use that figure instead, hence why I said that to achieve that you'd need to mock this... the choice depends on how the function will be used. Passing the `fig` gives a little more flexibility, but is less DRY. – Giacomo Alzetta Aug 03 '18 at 07:31
  • No no, the function plots a figure by taking some parameters. It does not take a figure as a parameter. I thought I wrote the question quite clearly. – Kristada673 Aug 03 '18 at 07:34
  • @GiacomoAlzetta I tried explaining the issue in the simplest way I could, but if you want the external function, here it is: https://github.com/slundberg/shap/blob/master/shap/plots.py Specifically, in this case, I am using the function `for i in features: shap.dependence_plot(i, shap_values, X)`. – Kristada673 Aug 03 '18 at 07:37
  • Just looking at the source code the approach you took should actually work. – ImportanceOfBeingErnest Aug 03 '18 at 09:09

1 Answers1

0

fig.savefig must be before show because when you close the figure, it is destroyed and only an empty (will appear blank) figure is saved.

There are several approaches, all of which require a modification of the external function that you don't want to change:

1 - modify the external function by adding a parameter to indicate if the figure must be saved or not, then using a conditional to save the figure or not.

def external function(params, dosave=False):
    ...
    if dosave:
        fig.savefig...
    fig.show()

2 - modify the external function to return a figure that you can then choose to save prior to displaying it.

3 - Possibly decorate the external function so it saves the figure.

There may be a 'hacky way' to use ipython internals to keep a handle on the figures you are closing, but I don't know it.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • Ok, so no escaping having to touch the source code, I see. Would it be possible to write a code to parse different jupyter notebook blocks and save figures if present? Just thinking aloud here. – Kristada673 Aug 03 '18 at 07:58
  • Probably. You'll have to look at how images are saved; I am unsure how to automate this. You also have the choice of saving the figure before closing it, but is it manually intensive work. – Reblochon Masque Aug 03 '18 at 08:04