Skip to content

Add channels_as_categories to render_images#576

Draft
timtreis wants to merge 3 commits intomainfrom
feature/issue-459-channels-as-categories
Draft

Add channels_as_categories to render_images#576
timtreis wants to merge 3 commits intomainfrom
feature/issue-459-channels-as-categories

Conversation

@timtreis
Copy link
Copy Markdown
Member

@timtreis timtreis commented Apr 3, 2026

Summary

  • Adds channels_as_categories: bool = False to render_images() — when True, shows a categorical legend mapping each channel name to its compositing color
  • Legend entries accumulate across chained render_images() calls and merge with labels/shapes legends on the same axes
  • Handles all multi-channel rendering paths: default RGB, palette, single cmap (sampled), and multi-cmap

Closes #459

Details

The feature follows the same deferred-draw pattern as colorbars: _render_images collects ChannelLegendEntry objects into a per-axis list, and _draw_channel_legend draws a single combined legend after the render loop completes. This avoids the matplotlib single-legend-per-axes limitation when chaining multiple render_images calls.

Edge cases handled:

  • Single channel / RGB(A): flag silently ignored (colorbar or native colors are more appropriate)
  • Single shared cmap across channels: legend skipped with a warning (channels aren't visually distinguishable)
  • Duplicate channel names: legend skipped with a warning
  • legend_loc="on data": falls back to "right margin" with a warning (no scatter coordinates for placement)
  • Multi-panel (multi_panel): avoids double-shrinking axes when a labels/shapes legend already applied the shrink

timtreis and others added 3 commits April 3, 2026 21:45
Add a `channels_as_categories: bool = False` parameter to
`render_images()` that shows a categorical legend mapping each
channel name to its compositing color for multi-channel images.

Legend entries are accumulated across chained `render_images()`
calls and drawn as a single combined legend after the render loop,
following the same deferred pattern as colorbars. When labels or
shapes also contribute legends on the same axes, the channel entries
merge automatically via matplotlib's artist-based legend collection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace local macOS baselines with CI-generated (Linux) images for
the 5 existing channel legend tests.  Add 2 new visual tests for
legend positioning (upper left, lower right) to verify legend_loc
is respected by the channel legend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace all 7 channel legend baselines with images generated on the
GitHub Actions runner (Linux) to match the CI rendering environment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.48780% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.43%. Comparing base (303140c) to head (14daabf).

Files with missing lines Patch % Lines
src/spatialdata_plot/pl/render.py 75.75% 5 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #576      +/-   ##
==========================================
+ Coverage   75.36%   75.43%   +0.07%     
==========================================
  Files          10       10              
  Lines        2935     2976      +41     
  Branches      684      691       +7     
==========================================
+ Hits         2212     2245      +33     
- Misses        441      446       +5     
- Partials      282      285       +3     
Files with missing lines Coverage Δ
src/spatialdata_plot/pl/basic.py 84.14% <100.00%> (+0.15%) ⬆️
src/spatialdata_plot/pl/render_params.py 86.82% <100.00%> (+0.32%) ⬆️
src/spatialdata_plot/pl/render.py 86.14% <75.75%> (-0.55%) ⬇️
🚀 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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Showing legend by defaults and allowing richer customizability

2 participants