Skip to content

Commit e4d3f9c

Browse files
committed
Fix flat hue in categorical density: drop min_alpha floor
For categorical density the only signal available to encode count is per-pixel alpha (hue is fixed per category by the color key). The existing min_alpha of ~254 (set so scatter plots render every point at full opacity) clamps that signal to a single value, so all three gene clusters were rendering as flat, uniform blobs. Under density=True the categorical shade path now uses min_alpha=40 (~15%): low enough to give the count-driven alpha real range, high enough to keep sparse-edge pixels visible under density_how="linear". Plain density (continuous shade path) is unaffected -- its viridis gradient already encodes count via hue.
1 parent 809c156 commit e4d3f9c

4 files changed

Lines changed: 10 additions & 1 deletion

File tree

src/spatialdata_plot/pl/_datashader.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ def _ds_shade_categorical(
281281
alpha: float,
282282
spread_px: int | None = None,
283283
how: str = "linear",
284+
density: bool = False,
284285
) -> Any:
285286
"""Shade a categorical or no-color datashader aggregate."""
286287
ds_cmap = None
@@ -289,12 +290,19 @@ def _ds_shade_categorical(
289290
if isinstance(ds_cmap, str) and ds_cmap[0] == "#":
290291
ds_cmap = _hex_no_alpha(ds_cmap)
291292

293+
# The default min_alpha (~254) is a near-full-opacity floor — right for scatter
294+
# plots, but it collapses the count-driven alpha range and makes categorical
295+
# density read as a flat hue cloud. Drop the floor under density so per-pixel
296+
# alpha can actually encode count. A small non-zero floor (~15%) keeps the
297+
# sparse edges visible under density_how="linear" instead of vanishing.
298+
min_alpha = 40.0 if density else _convert_alpha_to_datashader_range(alpha)
299+
292300
agg_to_shade = ds.tf.spread(agg, px=spread_px) if spread_px is not None else agg
293301
shaded = _datashader_map_aggregate_to_color(
294302
agg_to_shade,
295303
cmap=ds_cmap,
296304
color_key=color_key,
297-
min_alpha=_convert_alpha_to_datashader_range(alpha),
305+
min_alpha=min_alpha,
298306
how=how,
299307
)
300308
return _apply_user_alpha(shaded, alpha)

src/spatialdata_plot/pl/render.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ def _render_points(
11051105
render_params.alpha,
11061106
spread_px=px,
11071107
how=shade_how,
1108+
density=render_params.density,
11081109
)
11091110
else:
11101111
shaded, nan_shaded, reduction_bounds = _ds_shade_continuous(
-51.7 KB
Binary file not shown.
-38.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)