5

I'm trying to draw some SHAP plots in Python to gain a deeper understanding of the output of my machine learning models. This is the method I'm calling in a for loop:

def plotAndSaveSHAPSummary(model,train_data,x_train,pathToSHAPPlots):
    shap_values = model.get_feature_importance(train_data, type='ShapValues')
    expected_value = shap_values[0,-1]
    shap_values = shap_values[:,:-1]

    shap.summary_plot(shap_values,x_train,max_display=20,show=False)
    plt.savefig(pathToSHAPPlots+'/SHAP Plots/SHAP_Plot'+str(counter)+'.png',dpi=300,bbox_inches='tight')
    plt.clf()

The plots are saved to the disk as expected but after each call of the savefig method, I get the following error message:

Exception in Tkinter callback
Traceback (most recent call last):
  File "D:\PathTo\Anaconda\Lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "D:\PathTo\Anaconda\Lib\tkinter\__init__.py", line 749, in callit
    func(*args)
  File "D:\PathTo\Anaconda\lib\site-packages\matplotlib\backends\_backend_tk.py", line 270, in idle_draw
    self.draw()
  File "D:\PathTo\Anaconda\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 9, in draw
    super(FigureCanvasTkAgg, self).draw()
  File "D:\PathTo\Anaconda\lib\site-packages\matplotlib\backends\backend_agg.py", line 393, in draw
    self.figure.draw(self.renderer)
  File "D:\PathTo\Anaconda\lib\site-packages\matplotlib\backend_bases.py", line 1535, in _draw
    def _draw(renderer): raise Done(renderer)
matplotlib.backend_bases._get_renderer.<locals>.Done: <matplotlib.backends.backend_agg.RendererAgg object at 0x000002066B288288>

Any ideas how to get rid of this exception?

Hagbard
  • 2,139
  • 2
  • 16
  • 42
  • 4
    I ran into the same error recently using just matplotlib and resolved it (hackily) by adding a small plt.pause(1e-13) just before the savefig call. I don't know why this works, but assume there is a race condition somewhere in the matplotlib code. – Alex Gaudio Jun 11 '20 at 23:58

4 Answers4

4

I started getting this error too after update of one of the libs, probably matplot lib. The suggestion to use plt.pause described in the comment worked but it is internally calling plt.show() which was unacceptable for me. I ended up adding canvas.start_event_loop just before the savefig

import sys

def _save(self, filename: str) -> None:
   fig1 = plt.gcf()
   fig1.set_size_inches(6, 2.8)
   plt.draw()
   fig1.subplots_adjust(left=0.20)
   fig1.canvas.start_event_loop(sys.float_info.min) #workaround for Exception in Tkinter callback
   fig1.savefig(self.dst_dir + '/' + filename + '.png', dpi=220, bbox_inches='tight')
   fig1.clf()
   plt.close()
nan
  • 17,478
  • 6
  • 43
  • 74
1
plt.ioff()

did the trick for me

pawello2222
  • 23,992
  • 12
  • 59
  • 94
Marius
  • 11
  • 1
0

I have the same issue. I have a simple script in Python to make a chart that used to work fine, but now when it tries to save the file, that exact warning shows. I spent a lot of time trying to figure out what was happening, since the error was sudden and the message is not very informative.

I found out that it disappears when I omit the bbox_inches parameter at savefig.

I noticed the error started happening after I installed python-tk, but uninstalling it does not help.

[Mariu's answer] plt.ioff() doesn't work for me.

[nan's answer] fig1.canvas.start_event_loop(sys.float_info.min) does work.

Raphael
  • 656
  • 1
  • 5
  • 19
0

I was having the same problem when saving multiple plots with matplot lib. Adding plt.close() after saving the figure worked for me.