Skip to content

Commit d577db7

Browse files
Fixed multi-scale image/label handling (#131)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 267922a commit d577db7

File tree

5 files changed

+49
-25
lines changed

5 files changed

+49
-25
lines changed

CHANGELOG.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,20 @@ and this project adheres to [Semantic Versioning][].
88
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
99
[semantic versioning]: https://semver.org/spec/v2.0.0.html
1010

11-
## [Unreleased]
11+
## [0.0.3] - tbd
12+
13+
### Fixed
14+
15+
- Multi-scale images/labels are now correctly substituted and the action is logged (#131).
16+
17+
## [0.0.2] - 2023-06-25
18+
19+
### Fixed
20+
21+
- Multiple bugfixes of which I didn't keep track of.
22+
23+
## [0.0.1] - 2023-04-04
1224

1325
### Added
1426

15-
- Basic tool, preprocessing and plotting functions
27+
- Initial release of `spatialdata-plot` with support for `images`, `labels`, `points` and `shapes`.

src/spatialdata_plot/pl/basic.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
_get_extent,
4242
_maybe_set_colors,
4343
_mpl_ax_contains_elements,
44-
_multiscale_to_image,
4544
_prepare_cmap_norm,
4645
_prepare_params_plot,
4746
_robust_transform,
@@ -544,9 +543,6 @@ def show(
544543
if not all(isinstance(t, str) for t in title):
545544
raise TypeError("All titles must be strings.")
546545

547-
# Simplicstic solution: If the images are multiscale, just use the first
548-
sdata = _multiscale_to_image(sdata)
549-
550546
# get original axis extent for later comparison
551547
x_min_orig, x_max_orig = (np.inf, -np.inf)
552548
y_min_orig, y_max_orig = (np.inf, -np.inf)
@@ -608,19 +604,6 @@ def show(
608604
logg.info(f"Dropping coordinate system '{cs}' since it doesn't have relevant elements.")
609605
coordinate_systems = valid_cs
610606

611-
# print(coordinate_systems)
612-
# cs_mapping = _get_coordinate_system_mapping(sdata)
613-
# print(cs_mapping)
614-
615-
# check that coordinate system and elements to be rendered match
616-
# for cmd, params in render_cmds.items():
617-
# if params.elements is not None and len([params.elements]) != len(coordinate_systems):
618-
# print(params.elements)
619-
# raise ValueError(
620-
# f"Number of coordinate systems ({len(coordinate_systems)}) does not match number of elements "
621-
# f"({len(params.elements)}) in command {cmd}."
622-
# )
623-
624607
# set up canvas
625608
fig_params, scalebar_params = _prepare_params_plot(
626609
num_panels=len(coordinate_systems),

src/spatialdata_plot/pl/render.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import numpy as np
1111
import pandas as pd
1212
import scanpy as sc
13+
import spatial_image
1314
import spatialdata as sd
1415
from anndata import AnnData
1516
from geopandas import GeoDataFrame
@@ -19,6 +20,10 @@
1920
from matplotlib.patches import Circle, Polygon
2021
from pandas.api.types import is_categorical_dtype
2122
from scanpy._settings import settings as sc_settings
23+
from spatialdata.models import (
24+
Image2DModel,
25+
Labels2DModel,
26+
)
2227

2328
from spatialdata_plot._logging import logger
2429
from spatialdata_plot.pl.utils import (
@@ -342,8 +347,11 @@ def _render_images(
342347
elements = list(sdata_filt.images.keys())
343348

344349
images = [sdata.images[e] for e in elements]
350+
for img, img_key in zip(images, elements):
351+
if not isinstance(img, spatial_image.SpatialImage):
352+
img = Image2DModel.parse(img["scale0"].ds.to_array().squeeze(axis=0))
353+
logger.warning(f"Multi-scale images not yet supported, using scale0 of multi-scale image '{img_key}'.")
345354

346-
for img in images:
347355
if render_params.channel is None:
348356
channels = img.coords["c"].values
349357
else:
@@ -512,17 +520,21 @@ def _render_labels(
512520
if elements is None:
513521
elements = list(sdata_filt.labels.keys())
514522

515-
labels = [sdata.labels[e].values for e in elements]
523+
labels = [sdata.labels[e] for e in elements]
524+
525+
for label, label_key in zip(labels, elements):
526+
if not isinstance(label, spatial_image.SpatialImage):
527+
label = Labels2DModel.parse(label["scale0"].ds.to_array().squeeze(axis=0))
528+
logger.warning(f"Multi-scale labels not yet supported, using scale0 of multi-scale label '{label_key}'.")
516529

517-
for label, labels_key in zip(labels, elements):
518530
if sdata.table is None:
519531
instance_id = np.unique(label)
520532
table = AnnData(None, obs=pd.DataFrame(index=np.arange(len(instance_id))))
521533
else:
522534
instance_key = _get_instance_key(sdata)
523535
region_key = _get_region_key(sdata)
524536

525-
table = sdata.table[sdata.table.obs[region_key].isin([labels_key])]
537+
table = sdata.table[sdata.table.obs[region_key].isin([label_key])]
526538

527539
# get isntance id based on subsetted table
528540
instance_id = table.obs[instance_key].values
@@ -542,7 +554,7 @@ def _render_labels(
542554
if (render_params.fill_alpha != render_params.outline_alpha) and render_params.contour_px is not None:
543555
# First get the labels infill and plot them
544556
labels_infill = _map_color_seg(
545-
seg=label,
557+
seg=label.values,
546558
cell_id=instance_id,
547559
color_vector=color_vector,
548560
color_source_vector=color_source_vector,
@@ -565,7 +577,7 @@ def _render_labels(
565577

566578
# Then overlay the contour
567579
labels_contour = _map_color_seg(
568-
seg=label,
580+
seg=label.values,
569581
cell_id=instance_id,
570582
color_vector=color_vector,
571583
color_source_vector=color_source_vector,

test_sandbox_data.ipynb

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

tests/pl/test_upstream_plots.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,19 @@ def test_plot_can_render_transformations_raccoon_mapaxis(self, sdata_raccoon: Sp
4646
set_transformation(sdata_raccoon.images["raccoon"], map_axis, to_coordinate_system="global")
4747

4848
sdata_raccoon.pl.render_images().pl.render_labels().pl.render_shapes().pl.show()
49+
50+
51+
def test_plot_can_render_blobs_images(sdata_blobs: SpatialData):
52+
sdata_blobs.pl.render_images().pl.show()
53+
54+
55+
def test_plot_can_render_blobs_points(sdata_blobs: SpatialData):
56+
sdata_blobs.pl.render_points().pl.show()
57+
58+
59+
def test_plot_can_render_blobs_labels(sdata_blobs: SpatialData):
60+
sdata_blobs.pl.render_labels().pl.show()
61+
62+
63+
def test_plot_can_render_blobs_shapes(sdata_blobs: SpatialData):
64+
sdata_blobs.pl.render_shapes().pl.show()

0 commit comments

Comments
 (0)