Skip to content

Commit

Permalink
Add functions to interactive (#315)
Browse files Browse the repository at this point in the history
* Add functions to interactive

In this commit two functions are added to the interactive class.
get_layer grabs the layer name and returns the layer if it matches the user input.
add_text_to_polygons adds annotations to the chosen polygons/shapes layer

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add tests for new functions in interactive

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Loosen tests for interactive

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Edit interactive polygon tests to use correct example dataset

* Fix interactive test

* Fix mixed line endings

* trigger ci

* Apply suggestions from code review

improve readability

Co-authored-by: Grzegorz Bokota <[email protected]>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Luca Marconato <[email protected]>
Co-authored-by: Grzegorz Bokota <[email protected]>
  • Loading branch information
4 people authored Oct 9, 2024
1 parent 7d49c23 commit a38e286
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning][].
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
[semantic versioning]: https://semver.org/spec/v2.0.0.html

## [0.5.5] - 2024-10-07

### Added

- New function to grab layer by name #315 @minhtien-trinh
- New annotation function to add text to polygons #315 @minhtien-trinh

## [0.5.4] - 2024-xx-xx

### Fixed
Expand Down
25 changes: 25 additions & 0 deletions src/napari_spatialdata/_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING, Any

import napari
from napari.layers import Image, Labels, Points, Shapes
from napari.utils.events import EventedList
from spatialdata._types import ArrayLike

Expand Down Expand Up @@ -100,3 +101,27 @@ def run(self) -> None:
def screenshot(self) -> ArrayLike | Any:
"""Take a screenshot of the viewer in its current state."""
return self._viewer.screenshot(canvas_only=False)

def get_layer(self, layer_name: str) -> Image | Labels | Points | Shapes | None:
"""Get a layer by name."""
try:
return self._viewer.layers[layer_name]
except KeyError:
return None

def add_text_to_polygons(self, layer_name: str, text_annotations: list[str]) -> None:
"""Add text annotations to a polygon layer."""
polygon_layer = self.get_layer(layer_name)
if not polygon_layer:
raise ValueError(f"Polygon layer '{layer_name}' not found.")
if len(text_annotations) != len(polygon_layer.data):
raise ValueError(
f"The number of text annotations must match the number of polygons. "
f"Polygons: {len(polygon_layer.data)}, Text: {len(text_annotations)}."
)
polygon_layer.text = {
"string": text_annotations,
"size": 10,
"color": "red",
"anchor": "center",
}
29 changes: 29 additions & 0 deletions tests/test_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,32 @@ def test_plot_can_add_element_switch_cs(sdata_blobs: SpatialData):
assert i._sdata_widget.coordinate_system_widget._system == "global"
assert i._viewer.layers[-1].visible
i._viewer.close()


class TestInteractive(PlotTester, metaclass=PlotTesterMeta):
def test_get_layer_existing(self, sdata_blobs: SpatialData):
i = Interactive(sdata=sdata_blobs, headless=True)
i.add_element(element="blobs_image", element_coordinate_system="global")
layer = i.get_layer("blobs_image")
assert layer is not None, "Expected to retrieve the blobs_image layer, but got None"
assert layer.name == "blobs_image", f"Expected layer name 'blobs_image', got {layer.name}"
i._viewer.close()

def test_get_layer_non_existing(self, sdata_blobs: SpatialData):
i = Interactive(sdata=sdata_blobs, headless=True)
layer = i.get_layer("non_existing_layer")
assert layer is None, "Expected None for a non-existing layer, but got a layer"
i._viewer.close()

def test_add_text_to_polygons(self, sdata_blobs: SpatialData):
i = Interactive(sdata=sdata_blobs, headless=True)
i.add_element(element="blobs_polygons", element_coordinate_system="global")

# Mock polygon layer with some polygon data
text_annotations = ["Label 1", "Label 2", "Label 3", "Label 4", "Label 5"]
polygon_layer = i.get_layer("blobs_polygons")

# Verify that text is added
i.add_text_to_polygons(layer_name="blobs_polygons", text_annotations=text_annotations)
assert polygon_layer.text is not None, "Text annotations were not added to the polygon layer"
i._viewer.close()

0 comments on commit a38e286

Please sign in to comment.