Skip to content

fix(datashader): render_shapes in a non-global coordinate system (#782) - #783

Merged
timtreis merged 2 commits into
mainfrom
fix/issue-782
Oct 9, 2026
Merged

timtreis merged 2 commits into
mainfrom
fix/issue-782

Conversation

@timtreis

@timtreis timtreis commented Oct 9, 2026

Copy link
Copy Markdown
Member

Closes #782.

Problem

render_shapes(..., method="datashader") raises KeyError: 'global' when the shapes element has no "global" coordinate system (e.g. Visium HD data from spatialdata-io, which places elements in a custom CS). Datashader is used explicitly or automatically for >10k shapes, so this breaks the technology_visium_hd example notebooks.

Root cause

The datashader branch of _render_shapes wraps the already-transformed geometry with ShapesModel.parse(...) and then requests the canvas extent in a hardcoded "global" CS. Whether the GeoDataFrame constructor propagates the source element's .attrs is pandas/geopandas-version dependent:

  • When attrs propagate (reporter's fresh stack), the wrapped element carries only the real CS (my_sample), so the "global" lookup in _element_extent_fast raises KeyError: 'global'.
  • When attrs are dropped (older pandas), parse defaults to a global identity and it silently works.

Fix

In the datashader branch (src/spatialdata_plot/pl/render.py):

  • Drop any carried-over transform attr before parsing (otherwise ShapesModel.parse with transformations= would raise ValueError: Transformations are both specified for the element and also passed as an argument).
  • Tag the wrapped element with transformations={coordinate_system: Identity()} — the geometry is already in the target CS.
  • Compute the extent in coordinate_system instead of the hardcoded "global".

This mirrors the already-correct points datashader branch. The working (global) case is byte-identical — same coordinates, same extent — so no visual baselines change.

Notes

  • Verified the repro (blobs moved to a custom CS, rendered with method="datashader") and confirmed the fix holds in both attrs regimes (propagated / dropped).
  • No test added per maintainer preference; the behavior cannot go red→green in the current local pandas (attrs dropped by the constructor), and test_plot_* are CI-only.

The datashader branch of _render_shapes requested the canvas extent in a
hardcoded "global" CS. When the GeoDataFrame constructor propagates the
source element's transform attrs (pandas/geopandas-version dependent), the
re-wrapped element carries only the real CS and the "global" lookup in
_element_extent_fast raises KeyError.

Drop any carried-over transform attr, tag the wrapped element with an
identity transform in the resolved coordinate_system, and compute the extent
in that CS. Mirrors the points datashader branch.
test_groups_filtering_preserves_transformation hard-asserted that a bare
gpd.GeoDataFrame re-wrap strips .attrs (so _prepare_transformation raises).
Whether the GeoDataFrame constructor propagates .attrs is pandas/geopandas
version dependent, so that assertion fails on stacks that preserve them.

Keep the actual #420 guard (the spatialdata-managed element retains its
transform after groups filtering) and drop the brittle demonstration block
and now-dead re-wrap.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.10%. Comparing base (9f19b7d) to head (057bd5c).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #783   +/-   ##
=======================================
  Coverage   80.09%   80.10%           
=======================================
  Files          18       18           
  Lines        4863     4865    +2     
  Branches     1080     1080           
=======================================
+ Hits         3895     3897    +2     
  Misses        603      603           
  Partials      365      365           
Files with missing lines Coverage Δ
src/spatialdata_plot/pl/render.py 89.01% <100.00%> (+0.02%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@timtreis
timtreis merged commit bfda1fe into main Oct 9, 2026
11 checks passed
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(method="datashader") fails with KeyError: 'global' when the element has no "global" coordinate system

2 participants