Skip to content

fix(cpp): restore working feature_map bar rendering (SHAP alignment, sign, labels) + tests#334

Merged
breimanntools merged 3 commits into
masterfrom
fix/feature-map-shap-bar-order
Jul 3, 2026
Merged

fix(cpp): restore working feature_map bar rendering (SHAP alignment, sign, labels) + tests#334
breimanntools merged 3 commits into
masterfrom
fix/feature-map-shap-bar-order

Conversation

@breimanntools

@breimanntools breimanntools commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Restores several feature_map rendering behaviors that recent commits silently broke, and adds the regression tests that were missing. Traced with git log -S; each is reverted to the proven implementation rather than re-patched.

Fixes

  1. Right per-subcategory SHAP bars mis-ordered (0567abaa). Bars were drawn by category name, only for categories with impact, so matplotlib's categorical converter compacted them onto the top rows. Reverted to one value per category in row order + a single ax.barh(list_cat, values) (row-aligned).
  2. Top per-position SHAP bars inconsistent (0567abaa). They were a one-direction magnitude stack while the right bars are signed; a net-negative position read as an inflated upward bar. Reverted to the signed-diverging form (pos up / neg down) to match.
  3. Cumulative-importance % labels clipped by the heatmap (d59c4bb9). The labels were moved inside the bars (white, right-anchored) and lost 8465896b's clip_on=False, so short-bar labels ran left past the baseline and were hidden (e.g. 2.0%0%). Restored the never-cut form: label just outside the bar tip (extends right), clip_on=False.

Tests (this class now fails fast)

  • test_shap_impact_bar_aligns_with_correct_row, test_shap_impact_bars_map_one_to_one_to_rows — SHAP bars map 1:1 to rows.
  • test_shap_bars_are_signed_diverging (rewritten from a no-op that checked get_x()>=0) — both panels diverge in sign.
  • test_importance_bar_labels_extend_outward_not_clipped — no % label extends left of the baseline.

Full cpp_plot suite green (337). Only feature_map bar/label rendering is touched; independent of the auto_font / prediction PRs.

Known, NOT changed here (deliberate tuned layout; only affects explicit non-square figsizes, not the default or auto_font): the scale-category legend can sit off-figure for e.g. figsize=(12,6). Left for a separate decision.

🤖 Generated with Claude Code

The per-subcategory SHAP impact bars were misaligned: they piled onto the top rows
instead of their real subcategory rows. Root cause was commit 0567aba ('redesign
feature_map SHAP bars as per-feature cumulative stacks'), which replaced the working
implementation -- one value per category in row order, drawn with a single
ax.barh(list_cat, values) call -- with a per-feature ax.barh(<category name>, ...)
loop that only drew categories with impact, letting matplotlib's categorical converter
compact them onto the top rows.

Revert the SHAP bar rendering (and its x-limit) to that proven, aligned implementation.
Add two regression tests that would catch this class of bug early: a single-category
impact must land on its own row, and several impacted categories must map one-to-one to
their rows. Full cpp_plot suite green (336).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@breimanntools breimanntools force-pushed the fix/feature-map-shap-bar-order branch from 94152a0 to a168a2c Compare July 2, 2026 14:04
@breimanntools breimanntools changed the title fix(cpp): SHAP feature_map impact bars misaligned with subcategory rows fix(cpp): restore aligned SHAP feature_map impact bars (revert to working impl) + tests Jul 2, 2026
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.94%. Comparing base (1a152de) to head (f9319df).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #334   +/-   ##
=======================================
  Coverage   94.93%   94.94%           
=======================================
  Files         185      185           
  Lines       17883    17868   -15     
  Branches     3038     3028   -10     
=======================================
- Hits        16978    16965   -13     
+ Misses        598      597    -1     
+ Partials      307      306    -1     
Files with missing lines Coverage Δ
...e_engineering/_backend/cpp/cpp_plot_feature_map.py 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

Components Coverage Δ
cpp_core 94.95% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

breimanntools and others added 2 commits July 2, 2026 18:46
… weak sign test

Completes the SHAP-bar revert: the top per-position impact bars were left in the
0567aba magnitude-stack (one-direction, abs(v)) while the right subcategory bars are
signed-diverging, so the two panels disagreed (a net-negative position read as an
inflated upward bar). Revert the top bars to the working signed implementation
(pos up / neg down) to match. Rewrite test_shap_bars_are_one_direction ->
test_shap_bars_are_signed_diverging: the old test asserted get_x()/get_y() >= 0, which
is always true for bar/barh (the signed extent lives in get_width()/get_height()), so it
caught nothing and its premise was wrong post-revert. Now asserts both panels diverge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… by heatmap)

d59c4bb moved the cumulative-importance % labels inside the bars (white, right-anchored)
and dropped the clip_on=False that 8465896 had added, so short-bar labels ran left past
the x=0 baseline and were clipped/hidden under the heatmap (e.g. '2.0%' -> '0%'). Restore
the never-cut form: label just outside the bar tip (ha='left', extends right, away from
the heatmap) with clip_on=False. Add a regression test that no importance label extends
left of the baseline. (The ranking plot already handles this correctly.) cpp_plot green (337).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@breimanntools breimanntools changed the title fix(cpp): restore aligned SHAP feature_map impact bars (revert to working impl) + tests fix(cpp): restore working feature_map bar rendering (SHAP alignment, sign, labels) + tests Jul 2, 2026
@breimanntools breimanntools merged commit 1bd322f into master Jul 3, 2026
16 checks passed
@breimanntools breimanntools deleted the fix/feature-map-shap-bar-order branch July 3, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant