Python, shap package: How to plot a grid of dependence plots?

Viewed 3463

I am trying to plot a grid of dependence plots from the shap package. Here is MWE code for an example of what I want:

fig, axs = plt.subplots(2,8, figsize=(16, 4), facecolor='w', edgecolor='k') # figsize=(width, height)
fig.subplots_adjust(hspace = .5, wspace=.001)

axs = axs.ravel()

for i in range(10):

    axs[i].contourf(np.random.rand(12,12),5,cmap=plt.cm.Oranges)
    axs[i].set_title(str(250+i))

plt.show()

An example layout of what I want

Here is the code I have so far. A few things aren't working:

  1. The figure size of my grid aren't impacted by my figsize arguments
  2. My code plots bigger versions of my plots beneath the grid.
  3. Only one of the dependence plots is showing in the grid.
fig, axs = plt.subplots(1,8, figsize=(4, 2))
axs = axs.ravel()

for b in X_test.columns[:3]:
    for a in X_test.columns[:3]:
        shap.dependence_plot((a, b), shap_interaction_values, X_test)

An image of what I am getting: What I am getting.

2 Answers
import shap
import matplotlib.pyplot as plt

X = ...
shap_values = ...

columns = X.columns

# adjust nrows, ncols to fit all your columns
fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(20, 14))
axes = axes.ravel()

for i, col in enumerate(columns):
    shap.dependence_plot(col, shap_values, X, ax=axes[i], show=False)

I had the same problem as you - the code says that dependence_plot takes an optional parameter: ax

So you can make your subfigures and place your subsequent plots into that:



fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
shap.dependence_plot((a, b), shap_interaction_values, X_test, ax=ax1)
shap.dependence_plot((a, b), shap_interaction_values, X_test, ax=ax2)

In your case you can zip() the axes and the columns together.

I have not solved yet what to do in case of using interaction_index - in that case, you'll get all possible interaction_indexes heatmaps at the end of your figure, which looks very bad.

Edit: Ugly hack but it seems to do the deal - if you specify interaction_index for each of the dependence_plots then it will plot one colorbar for each plot into the last subplot, which looks awful.

I ended up manually deleting the axes (each colorbar is one additional axis) and then automatically readjusted the subplots:

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, constrained_layout=True)
shap.dependence_plot((a, b), shap_interaction_values, X_test, ax=ax1)
shap.dependence_plot((a, b), shap_interaction_values, X_test, ax=ax2)
fig.axes[-1].remove()
fig.axes[-1].remove()

This will get rid of all colorbars, and constrained_layout=True will ensure that the last subfigure is redrawn correctly, without this parameter it will stay 'squished' to make space for the non-existent colorbars.

Related