Skip to content

Commit 293d41c

Browse files
authored
fix: align rasterized artists with get_extent (#742)
1 parent 50a6606 commit 293d41c

37 files changed

Lines changed: 91 additions & 4 deletions

File tree

src/spatialdata_plot/pl/_datashader.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,10 @@ def _ax_show_and_transform(
730730
norm: Normalize | None = None,
731731
interpolation: str | None = None,
732732
) -> matplotlib.image.AxesImage:
733-
# ``extent`` uses mpl's pixel-grid convention; world placement happens via
734-
# ``set_transform(trans_data)`` afterwards.
735-
image_extent = (-0.5, array.shape[1] - 0.5, array.shape[0] - 0.5, -0.5)
733+
# Pixel-edge extent [0, W] x [0, H], matching get_extent (which sets the axis limits)
734+
# and the affine's data box (placement is via set_transform below). mpl's default
735+
# pixel-center extent (-0.5, W-0.5, ...) offsets by half a pixel, amplified by the affine.
736+
image_extent = (0.0, array.shape[1], array.shape[0], 0.0)
736737
# ``alpha`` is applied only when no cmap is set, so RGBA arrays already
737738
# carrying per-pixel alpha (e.g. datashader output) are not double-attenuated.
738739
imshow_kwargs: dict[str, Any] = {"zorder": zorder, "extent": image_extent, "norm": norm}

src/spatialdata_plot/pl/render.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,16 @@ def _draw_labels(
24002400
# non-linear norm (LogNorm/PowerNorm). Display the RGB without a norm and build the
24012401
# continuous colorbar mappable separately from the resolved norm (mirrors the outline path),
24022402
# so the colorbar reflects the real norm subclass.
2403-
img = ax.imshow(labels, rasterized=True, alpha=alpha, origin="lower", zorder=render_params.zorder)
2403+
# Pixel-edge extent (0, W, 0, H) matching get_extent/the affine box; mpl's default
2404+
# pixel-center extent would offset labels half a pixel. Order follows origin="lower".
2405+
img = ax.imshow(
2406+
labels,
2407+
rasterized=True,
2408+
alpha=alpha,
2409+
origin="lower",
2410+
extent=(0.0, labels.shape[1], 0.0, labels.shape[0]),
2411+
zorder=render_params.zorder,
2412+
)
24042413
img.set_transform(trans_data)
24052414
if color_spec.is_categorical:
24062415
return img
85 Bytes
Loading
-5.05 KB
Loading
11.8 KB
Loading
252 Bytes
Loading
232 Bytes
Loading
34 Bytes
Loading
108 Bytes
Loading
169 Bytes
Loading

0 commit comments

Comments
 (0)