Bug incorrect plot displayed after sorting table rows in webapp#690
Bug incorrect plot displayed after sorting table rows in webapp#690dalestee wants to merge 28 commits intoMAIF:masterfrom
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes incorrect row/line selection in the Shapash webapp after DataTable sorting by using the user-visible (viewport) table data, and modernizes the codebase for Python 3.11–3.14 (typing updates, CI + tooling, and minor formatting cleanups).
Changes:
- Webapp: use
derived_viewport_datato mapactive_cellto the correct_index_after sorting/filtering; adjust row highlighting accordingly. - Compatibility: bump supported Python versions to
>=3.11,<3.15and update CI/pre-commit/tests/docs to match. - Refactors: replace
typing.Optional/Unionstyle hints with PEP 604 unions and updatezip(..., strict=False)usage in several places.
Reviewed changes
Copilot reviewed 34 out of 36 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit_tests/utils/test_load_smartpredictor.py | Update version-based pickle path selection via sys.version_info (adds 3.14). |
| tests/unit_tests/explainer/test_smart_plotter.py | Minor string formatting change in expected Plotly bar labels. |
| tests/unit_tests/explainer/test_smart_explainer.py | Update version-based pickle path selection via sys.version_info (adds 3.14). |
| test | Adds/modifies an empty top-level file named test. |
| shapash/webapp/webapp_launch.py | Minor formatting (spacing) in printed pandas indexing. |
| shapash/webapp/utils/callbacks.py | Typing modernizations (PEP 604 unions) in function signatures. |
| shapash/webapp/smart_app.py | Main webapp fix: use viewport data for selection/highlighting; improve y_pred handling for Series/DataFrame. |
| shapash/utils/utils.py | Add strict=False to zip() calls (Python 3.10+ API). |
| shapash/utils/transform.py | Typing modernization in isinstance usage. |
| shapash/utils/clustering.py | Typing modernization (PEP 604 unions). |
| shapash/utils/check.py | Typing modernization in isinstance usage. |
| shapash/report/project_report.py | Typing modernization (PEP 604 unions). |
| shapash/report/generation.py | Typing modernization (PEP 604 unions). |
| shapash/report/data_analysis.py | Typing modernization (PEP 604 unions). |
| shapash/report/common.py | Typing modernization (PEP 604 unions). |
| shapash/report/base_report.ipynb | Formatting tweaks (quotes/line wrapping). |
| shapash/plots/plot_univariate.py | Typing modernization + zip(..., strict=False) in hovertext generation. |
| shapash/plots/plot_stability.py | zip(..., strict=False) in hovertext generation. |
| shapash/plots/plot_line_comparison.py | zip(..., strict=False) usage. |
| shapash/plots/plot_feature_importance.py | zip(..., strict=False) usage. |
| shapash/plots/plot_evaluation_metrics.py | Typing modernization + zip(..., strict=False) usage in hovertext. |
| shapash/plots/plot_correlations.py | Typing modernization + minor f-string formatting cleanup. |
| shapash/plots/plot_contribution.py | zip(..., strict=False) usage in hovertext. |
| shapash/plots/plot_bar_chart.py | zip(..., strict=False) usage in bar loop. |
| shapash/manipulation/summarize.py | zip(..., strict=False) usage. |
| shapash/manipulation/select_lines.py | zip(..., strict=False) usage in classification contribution selection. |
| shapash/explainer/smart_state.py | Typing modernization in isinstance. |
| shapash/explainer/smart_plotter.py | Typing modernization + zip(..., strict=False) usage; minor error message formatting. |
| shapash/explainer/multi_decorator.py | zip(..., strict=False) usage and minor error message formatting. |
| shapash/explainer/consistency.py | zip(..., strict=False) usage in colorscale/plots. |
| shapash/decomposition/contributions.py | Minor error message spelling/formatting fix. |
| shapash/backend/base_backend.py | Typing modernization (PEP 604 unions) and minor message formatting. |
| pyproject.toml | Bump supported Python versions to >=3.11,<3.15 and classifiers to include 3.14. |
| README.md | Update stated supported Python versions (3.11–3.14). |
| .pre-commit-config.yaml | Update pyupgrade version and target --py311-plus. |
| .github/workflows/main.yml | Update CI matrix to Python 3.11–3.14. |
Comments suppressed due to low confidence (1)
shapash/webapp/smart_app.py:171
- In the
y_pred-as-listbranch,self.predict_colis initialized as a list (see__init__), and the code wraps it again ascolumns=[self.predict_col]. This produces an unhashable/list column label and the subsequentrename(columns={f"{self.predict_col}": "_predict_"})won't match the actual column name. Makepredict_cola string and pass a list of strings tocolumns(or hardcode['_predict_']) so the joined column can be reliably renamed/accessed.
elif isinstance(self.explainer.y_pred, list):
self.dataframe = self.dataframe.join(
pd.DataFrame(
data=self.explainer.y_pred, columns=[self.predict_col], index=self.explainer.x_init.index
)
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| description = "Shapash is a Python library which aims to make machine learning interpretable and understandable by everyone." | ||
| readme = "README.md" | ||
| requires-python = ">=3.9, <3.14" | ||
| requires-python = ">=3.11, <3.15" |
There was a problem hiding this comment.
The PR description focuses on a webapp table-sorting selection bug, but this change also bumps the supported Python range (drops 3.9/3.10 and adds 3.14) and updates CI/pre-commit accordingly. Please update the PR description/title to reflect this broader compatibility change, or split the Python version bump into a separate PR for easier review/release notes.
| selected = clusters["points"][0]["customdata"] | ||
| elif ctx.triggered[0]["prop_id"] == "dataset.active_cell": | ||
| selected = data[cell["row"]]["_index_"] | ||
| selected = viewport_data[cell["row"]]["_index_"] |
There was a problem hiding this comment.
derived_viewport_data can be None (or missing expected keys) depending on DataTable state; indexing into viewport_data[cell["row"]] will raise a TypeError/KeyError and break row selection. Consider falling back to data when viewport_data is None, and guard for out-of-range rows before reading _index_.
| selected = viewport_data[cell["row"]]["_index_"] | |
| displayed_data = viewport_data if viewport_data is not None else data | |
| row = cell.get("row") if isinstance(cell, dict) else None | |
| if ( | |
| isinstance(displayed_data, list) | |
| and isinstance(row, int) | |
| and 0 <= row < len(displayed_data) | |
| and isinstance(displayed_data[row], dict) | |
| and "_index_" in displayed_data[row] | |
| ): | |
| selected = displayed_data[row]["_index_"] | |
| else: | |
| selected = current_index_id |
Description
Fixing bug where the selection of line for the plot doesnt work after sorting the table
Main Changes
Instead of retrieving the line from the raw table. We retrieve it from the table that the user is seeing.
Such as that: