Skip to content

fix: render unannotated shapes with na_color instead of dropping them#711

Merged
timtreis merged 3 commits into
mainfrom
fix/issue-710
Jun 10, 2026
Merged

fix: render unannotated shapes with na_color instead of dropping them#711
timtreis merged 3 commits into
mainfrom
fix/issue-710

Conversation

@timtreis

@timtreis timtreis commented Jun 10, 2026

Copy link
Copy Markdown
Member

Closes #710.

What

render_shapes colored by a table column silently dropped shapes whose instance had no row in the table (_join_table_for_element(how="inner")). This renders them with na_color instead — consistent with the points (how="left" merge) and labels (raster + na_color) paths, and with the scanpy/squidpy convention.

# 20 shapes, table annotates 12
sdata.pl.render_shapes("shapes", color="val").pl.show()
# before: 12 shapes drawn (8 silently disappear)
# after:  20 shapes drawn (8 unannotated -> na_color)

How

One-line behavior change: _join_table_for_element uses how="left" instead of how="inner", so every shape survives the join. The per-shape color lookup (_extract_color_column, from #709, reindexed to the element) then yields NaN → na_color for the unannotated shapes via the existing NaN-handling path (which also emits the existing "Found N NaN values… colored with na_color" warning). No new color logic.

Scope / safety

  • Behavior-only, deliberately separate from the performance work — minimal diff (utils.py + a test). The structural join still runs; removing it (the remaining color-copy speedup) is a separate follow-up.
  • Fully-annotated data is unaffected — verified pixel-identical (inner == left when nothing is dropped) for continuous, categorical, and gene coloring. So existing visual baselines should not change; only partial-annotation fixtures (if any) change — those would be a deliberate, reviewable baseline update.
  • Builds on perf(color): extract one aligned column instead of copying the whole table #709 (_extract_color_column), which is already on main.

Test

Adds test_render_shapes_unannotated_shapes_get_na_color_not_dropped — a real regression test: it fails on the old code (expected all 20 shapes rendered, got 12 (unannotated dropped)) and passes on the fix (20 rendered, 8 in na_color). There was previously no test covering this behavior, which is why the inconsistency went unnoticed.

@timtreis timtreis changed the title fix: render unannotated shapes with na_color instead of dropping them (#710) fix: render unannotated shapes with na_color instead of dropping them Jun 10, 2026
@timtreis timtreis force-pushed the fix/issue-710 branch 2 times, most recently from ec8b016 to e34f7db Compare June 10, 2026 14:54
…dropping them (#710)

render_shapes joined the element to its table with how="inner", silently dropping shapes whose
instance had no table row. Points (how="left" merge) and labels (raster + na_color) keep unannotated
elements, so shapes were the inconsistent outlier (and it broke the labels<->shapes interchangeability).

Switch _join_table_for_element to how="left": all shapes survive, and the per-shape color lookup
(_extract_color_column, reindexed to the element) yields NaN -> na_color for the unannotated ones, via
the existing NaN-handling path. Fully-annotated data is unaffected (verified pixel-identical: inner == left
when nothing is dropped), so only partial-annotation output changes.

Adds two visual regression tests: coloring blobs_polygons by a table column renders the unannotated polygon (instance 0, no table row) with na_color instead of dropping it, and na_color=None hides it again.
polygon (instance 0 has no table row) with na_color instead of dropping it.
timtreis added 2 commits June 10, 2026 17:06
Unannotated shapes now render with na_color (non_matching_table, fill_and_outline, custom_colors_from_uns),
and the element keeps its original draw order instead of the inner-join's scramble (the shuffling/queried
tests). All renders verified correct against the new behavior.
@timtreis timtreis merged commit 2066b57 into main Jun 10, 2026
6 of 8 checks passed
@timtreis timtreis deleted the fix/issue-710 branch June 10, 2026 15:40
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.39%. Comparing base (8d74219) to head (6fb510f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #711      +/-   ##
==========================================
- Coverage   76.42%   76.39%   -0.03%     
==========================================
  Files          14       14              
  Lines        4330     4330              
  Branches     1006     1006              
==========================================
- Hits         3309     3308       -1     
  Misses        664      664              
- Partials      357      358       +1     
Files with missing lines Coverage Δ
src/spatialdata_plot/pl/render.py 87.08% <ø> (ø)
src/spatialdata_plot/pl/utils.py 69.07% <ø> (-0.05%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

render_shapes silently drops unannotated shapes when coloring by a table column (inconsistent with points/labels, which use na_color)

2 participants