New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support returning the actual matplotlib Figure #3494
Conversation
I wanted to make quite the same PR, as for example shap.plots.scatter does currently not return anything, even if show=False. Definitely should be fixed and harmonized across the different plot types. |
Shouldn't calling import xgboost
import matplotlib.pyplot as plt
import shap
# train XGBoost model
X, y = shap.datasets.adult(n_points=1000)
model = xgboost.XGBClassifier().fit(X, y)
# compute SHAP values
explainer = shap.Explainer(model, X)
shap_values = explainer(X)
shap.plots.bar(shap_values, show=False)
fig = plt.gcf()
fig.savefig('shap_bar_plot.png') This still gives me the same figure as expected. Edit: @JSchoeck I totally agree that this should be harmonized and the solution provided by @richarddli might be a generally applicable but that needs to be discussed if it is viable for all plots. @connortann what do you think about this? |
The Jupyter notebook implementation that I'm using in VSCode automatically invokes I would also suggest that this approach seems like a much cleaner separation of concerns than something like Line 508 in 5768d11
_force.py in particular takes a bunch of args that it passes to matplotlib such as figsize . I think having each plot return a matplotlib figure (or equiv), and then a separate set of functions (if desired) to manipulate these figures, is a much cleaner implementation.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also do not see a downside to this and if this helps users, then it's fine for me.
Thanks for the PR! This is a good step towards #3411 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #3494 +/- ##
=======================================
Coverage 59.23% 59.24%
=======================================
Files 90 90
Lines 12728 12729 +1
=======================================
+ Hits 7540 7541 +1
Misses 5188 5188 ☔ View full report in Codecov by Sentry. |
Overview
I'm using SHAP in software (as opposed to a Jupyter notebook). One use case I would like to do is display the SHAP bar chart from an Explanation object. With Force plots, there is an HTML method that returns raw HTML. I've implemented a simple alternative to adding the HTML method everywhere.
In essence, if show=False, return the actual current matplotlib Figure. This means that the calling function can then manipulate the actual figure. This approach also means that a lot of the styling / color options that are part of the library can be made directly on the Figure itself, instead of passing through to the actual plot.
If this approach is acceptable, I'd suggest modifying all the other plot functions as well to behave similarly.
Please let me know your thoughts! cc @CloseChoice