I am trying to customize the force_plot colors with Seaborn but I am getting the following exceptions, according to whether I use as_cmap=True:
plot_cmap=sns.diverging_palette(15, 155, s=99, l=70, n=2)
results in:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
shap/plots/force.py in force_plot(base_value, shap_values, features, feature_names, out_names, link, plot_cmap)
92 DenseData(np.zeros((1, len(feature_names))), list(feature_names))
93 )
---> 94 return visualize(e, plot_cmap)
95
96 else:
shap/plots/force.py in visualize(e, plot_cmap)
188
189 def visualize(e, plot_cmap="RdBu"):
--> 190 plot_cmap = verify_valid_cmap(plot_cmap)
191 if isinstance(e, AdditiveExplanation):
192 return AdditiveForceVisualizer(e, plot_cmap=plot_cmap).html()
shap/plots/force.py in verify_valid_cmap(cmap)
183 _rgbstring = re.compile(r'#[a-fA-F0-9]{6}$')
184 for color in cmap:
--> 185 assert(bool(_rgbstring.match(color))),"Invalid color found in CMAP."
186
187 return cmap
TypeError: cannot use a string pattern on a bytes-like object
And setting as_cmap=True
plot_cmap=sns.diverging_palette(15, 155, s=99, l=70, n=2, as_cmap=True)
results in:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
shap/plots/force.py in force_plot(base_value, shap_values, features, feature_names, out_names, link, plot_cmap)
92 DenseData(np.zeros((1, len(feature_names))), list(feature_names))
93 )
---> 94 return visualize(e, plot_cmap)
95
96 else:
shap/plots/force.py in visualize(e, plot_cmap)
188
189 def visualize(e, plot_cmap="RdBu"):
--> 190 plot_cmap = verify_valid_cmap(plot_cmap)
191 if isinstance(e, AdditiveExplanation):
192 return AdditiveForceVisualizer(e, plot_cmap=plot_cmap).html()
shap/plots/force.py in verify_valid_cmap(cmap)
178 def verify_valid_cmap(cmap):
179 assert (isinstance(cmap, str) or isinstance(cmap, list) or str(type(cmap)).endswith("unicode'>")
--> 180 ),"Plot color map must be string or list! not: " + str(type(cmap))
181 if isinstance(cmap, list):
182 assert (len(cmap) > 1), "Color map must be at least two colors."
AssertionError: Plot color map must be string or list! not: <class 'matplotlib.colors.LinearSegmentedColormap'>
Ah. The problem here is that force_plot uses javascript and D3 for rendering, not matplotlib, so you need to pass a list of colors to use. Pass a list of two colors to replace the default red and blue as hex strings (or some other string valid in CSS). You could probably get these colors from seaborn by evaluating their cmap at the values you want and passing the result as a list.
Hi, this still appears to not be working:
display(shap.force_plot(expected_val, shap_vals[shap_index_list[0],:], X.iloc[shap_index_list[0],:], matplotlib=True,text_rotation=30, link='logit', show = True, plot_cmap=['#00bfff','#ffffff']))
I receive no error, however the default colors remain.
'plot_cmap' for force_plots doesn't work for me as well. I need to convert the colors to a grey and black combination.
I tested with the examples given in - https://shap.readthedocs.io/en/latest/example_notebooks/tree_explainer/Force%20Plot%20Colors.html.
It plots the defaults colors.
Most helpful comment
Ah. The problem here is that force_plot uses javascript and D3 for rendering, not matplotlib, so you need to pass a list of colors to use. Pass a list of two colors to replace the default red and blue as hex strings (or some other string valid in CSS). You could probably get these colors from seaborn by evaluating their cmap at the values you want and passing the result as a list.