Report
Hi, using spatialdata 0.6.1, spatialdata_plot 0.3.3 I observe a very strange behaviour: figure displays different H&E depending on the figure dimensions.
Problem is somewhere in the logic handling decisions from _multiscale_to_spatial_image with regards to bounding_box_query perhaps
def crop0(x):
return sd.bounding_box_query(
x,
min_coordinate=[20_500, 8000],
max_coordinate=[21_000, 8500],
axes=("x", "y"),
target_coordinate_system="global",
)
fig, ax = plt.subplots(figsize=(5, 5))
crop0(s).pl.render_images("wsi").pl.render_points(
"transcripts",
color="feature_name",
s=1,
groups="Alb",
palette="orange",
).pl.show(ax=ax, title="H&E imag (5x5)", coordinate_systems="global")
fig, ax = plt.subplots(figsize=(6, 6))
crop0(s).pl.render_images("wsi").pl.render_points(
"transcripts",
color="feature_name",
s=1,
groups="Alb",
palette="orange",
).pl.show(ax=ax, title="H&E image (6x6)", coordinate_systems="global")
I have also added print statement to _multiscale_to_spatial_image and this is the output:
# For 5x5 image
Got request with dpi=100.0, width=5.0, scale=None
Chose scale0
# For 6x6 image
Got request with dpi=100.0, width=6.0, scale=None
Chose scale1
I suppose this choice should be the other way around, right? Larger image size should load higher-resolution image (scale0, not scale1).
Versions
| Package | Version |
| ---------------- | --------- |
| matplotlib | 3.10.8 |
| lazyslide | 0.10.0 |
| wsidata | 0.8.2 |
| scanpy | 1.12 |
| tifffile | 2026.2.16 |
| pandas | 2.3.3 |
| numpy | 2.3.5 |
| shapely | 2.1.2 |
| seaborn | 0.13.2 |
| spatialdata | 0.6.1 |
| spatialdata-plot | 0.3.3 |
| psutil | 7.2.2 |
| rtree | 1.4.1 |
| dask | 2024.11.2 |
| xarray | 2026.2.0 |
| spatialdata-io | 0.6.0 |
| Dependency | Version |
| ------------------------ | ---------------------------------------------------------- |
| typing-inspection | 0.4.2 |
| requests | 2.32.5 |
| xarray-schema | 0.0.3 |
| h11 | 0.16.0 |
| torch | 2.10.0 (2.10.0+cu128) |
| jedi | 0.19.2 |
| mpmath | 1.3.0 |
| multipledispatch | 1.0.0 (0.6.0) |
| pytz | 2026.1.post1 |
| pyarrow | 23.0.1 |
| comm | 0.2.3 |
| setuptools | 80.10.2 |
| anyio | 4.12.1 |
| threadpoolctl | 3.6.0 |
| natsort | 8.4.0 |
| Pint | 0.25.3 |
| httpcore | 1.0.9 |
| rich | 14.3.3 |
| huggingface_hub | 1.3.7 |
| donfig | 0.8.1.post1 |
| tblib | 3.2.2 |
| session-info2 | 0.4 |
| debugpy | 1.8.20 |
| torchvision | 0.25.0 (0.25.0+cu128) |
| anndata | 0.12.6 |
| h5py | 3.15.1 |
| timm | 1.0.24 |
| xarray-dataclass | 3.0.0 |
| click | 8.3.1 |
| matplotlib-scalebar | 0.9.0 |
| Deprecated | 1.3.1 |
| scikit-learn | 1.8.0 |
| networkx | 3.6.1 |
| pyproj | 3.7.2 |
| legacy-api-wrap | 1.5 |
| sympy | 1.14.0 |
| flexparser | 0.4 |
| ipython | 9.10.0 |
| urllib3 | 2.6.3 |
| pathlib_abc | 0.5.2 |
| llvmlite | 0.46.0 |
| pyct | 0.6.0 |
| xarray-spatial | 0.9.1 |
| idna | 3.11 |
| Pygments | 2.19.2 |
| tornado | 6.5.4 |
| xmltodict | 1.0.4 |
| stack-data | 0.6.3 |
| cuda-bindings | 12.9.4 |
| geopandas | 1.1.2 |
| ome-zarr | 0.12.2 |
| wcwidth | 0.5.3 |
| pydantic-extra-types | 2.11.1 |
| platformdirs | 4.5.1 |
| pydantic | 2.12.5 |
| jupyter_core | 5.9.1 |
| asttokens | 3.0.1 |
| kiwisolver | 1.4.9 |
| opencv-python | 4.13.0.92 (4.13.0) |
| typing_extensions | 4.15.0 |
| universal_pathlib | 0.3.10 |
| backports.tarfile | 1.2.0 |
| more-itertools | 10.8.0 |
| statsmodels | 0.14.6 |
| fsspec | 2026.1.0 |
| ipywidgets | 8.1.8 |
| jupyter_client | 8.8.0 |
| jaraco.context | 6.1.0 |
| numcodecs | 0.15.1 |
| executing | 2.2.1 |
| annotated-types | 0.7.0 |
| zarr | 3.1.5 |
| wrapt | 2.1.1 |
| flexcache | 0.3 |
| cuda-pathfinder | 1.3.3 (12.9.4) |
| MarkupSafe | 3.0.3 |
| prompt_toolkit | 3.0.52 |
| packaging | 26.0 |
| ipykernel | 7.1.0 |
| FlowIO | 1.4.0 |
| ujson | 5.12.0 |
| httpx | 0.28.1 |
| patsy | 1.0.2 |
| lxml | 6.0.2 |
| safetensors | 0.7.0 |
| certifi | 2026.1.4 (2026.01.04) |
| ome-types | 0.6.3 (xsdata_pydantic_basemodel: 0.1.0, ome_types: 0.6.3) |
| locket | 1.0.0 |
| msgpack | 1.1.2 |
| tiffslide | 3.0.0 |
| sortedcontainers | 2.4.0 |
| legendkit | 0.3.6 |
| parso | 0.8.5 |
| tqdm | 4.67.2 |
| matplotlib-inline | 0.2.1 |
| six | 1.17.0 |
| lazy_loader | 0.4 |
| xsdata | 26.2 |
| scikit-image | 0.26.0 |
| joblib | 1.5.3 |
| charset-normalizer | 3.4.4 |
| pyzmq | 27.1.0 |
| readfcs | 2.1.0 |
| jaraco.functools | 4.4.0 |
| PIMS | 0.7 |
| pillow | 12.1.0 |
| traitlets | 5.14.3 |
| dask-image | 2025.11.0 |
| spatial_image | 1.2.3 |
| ImageIO | 2.37.2 |
| triton | 3.6.0 |
| pydantic_core | 2.41.5 |
| cycler | 0.12.1 |
| toolz | 1.1.0 |
| filelock | 3.20.3 |
| scipy | 1.17.0 |
| google-crc32c | 1.8.0 |
| numba | 0.63.1 |
| pure_eval | 0.2.3 |
| jaraco.text | 4.0.0 |
| imagecodecs | 2026.1.14 |
| slicerator | 1.1.0 |
| python-dateutil | 2.9.0.post0 |
| multiscale_spatial_image | 2.0.3 |
| datashader | 0.18.2 |
| cloudpickle | 3.1.2 |
| distributed | 2024.11.2 |
| zict | 3.0.0 |
| decorator | 5.2.1 |
| attrs | 25.4.0 |
| opencv-python-headless | 4.13.0.92 (4.13.0) |
| fast-array-utils | 1.3.1 |
| Jinja2 | 3.1.6 |
| PyYAML | 6.0.3 |
| pyparsing | 3.3.2 |
| Component | Info |
| --------- | ------------------------------------------------------------------------------ |
| Python | 3.13.11 | packaged by conda-forge | (main, Jan 26 2026, 23:57:06) [GCC 14.3.0] |
| OS | Linux-4.18.0-425.19.2.el8_7.x86_64-x86_64-with-glibc2.28 |
| Updated | 2026-04-13 20:43 |
Report
Hi, using spatialdata 0.6.1, spatialdata_plot 0.3.3 I observe a very strange behaviour: figure displays different H&E depending on the figure dimensions.
Problem is somewhere in the logic handling decisions from
_multiscale_to_spatial_imagewith regards to bounding_box_query perhapsI have also added print statement to
_multiscale_to_spatial_imageand this is the output:I suppose this choice should be the other way around, right? Larger image size should load higher-resolution image (scale0, not scale1).
Versions