-
Notifications
You must be signed in to change notification settings - Fork 10
Highlight objects #455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Highlight objects #455
Conversation
…version for points layer) Refactors the object focusing logic to correctly apply combined affine transformations (rotation, scale, shear, translation) when centering the viewer on a selected object. Adds a helper function to build the affine matrix and ensures only the selected layer's objects are considered for focusing.
Added support for focusing on selected objects in Labels layers by computing the center of the selected label and applying affine transformations. Introduced helper functions for affine transformation and default zoom calculation to improve camera centering and zooming behavior.
Improved the logic for focusing on selected objects in napari layers by refactoring affine transformation application and camera setting into dedicated functions. Enhanced code clarity, modularity, and error handling for single object selection, and streamlined the process for both Points and Labels layers.
Extended the _focus_object function to handle napari Surface, Shapes, and Tracks layers. Each layer type now computes the center and applies the affine transformation before setting the viewer camera. Also fixed center calculation for Points and Labels layers.
This PR seems to be somewhat related to #441 . Here we highlight a point in the plotter and get a focusing effect in the corresponding object in the napari layer. There, if I understood it correctly, it is the other way around ? |
Replaces boolean indexing with integer indexing for shape selection in the _focus_object function to ensure compatibility with list of arrays in napari.layers.Shapes.
Replaces the custom _build_affine_matrix function with napari's Affine class for constructing affine transformation matrices. This simplifies the code and leverages napari's built-in utilities for affine transformations.
Correct! Full bi-directionality :) As for this PR, I think the new way of calculating the Orrr we both try it and see how it feels ona few datasets. ^^" |
The _calculate_default_zoom function and its usage in _set_viewer_camera have been commented out. This prepares for potential future implementation of zooming in on highlighted objects, but currently leaves the functionality inactive.
for more information, see https://pre-commit.ci
Introduces two tests to verify that the viewer camera centers and dims step update correctly when a single or multiple points layers have highlighted selections in 3D mode. These tests ensure proper behavior when focusing on selected points, including handling of layer translations.
…i-clusters-plotter into highlight_objects
for more information, see https://pre-commit.ci
…i-clusters-plotter into highlight_objects
for more information, see https://pre-commit.ci
Simplified the logic for selecting the center of a track in the _focus_object function by using a ternary operator, as suggested by SIM108. Required by pre-commit.
Alright, so I commented the zoom part for now, added tests for the points layer, solved conflicts, and fixed the pre-commit complaints. An unhighlighting feature is not needed if we don't zoom in IMO, but we may bring it in at another PR. Tests were passing locally, not sure why they are failing now. I can check here again next week as I will be out for a couple days. @jo-mueller feel free to jump in if you find the need to have this merged before that. |
@zoccoler I think I see what's happening - in some recent change, I changed the layer indexing to be done by uuid. But, as it turns out, querying a layer from the viewer like this |
…ot-uuids Use layer names for indexing, not uuids
for more information, see https://pre-commit.ci
Hi @zoccoler , I looked into the failing test and it's basically because some of the tests only work with "napari>=0.6.5". Wei could either adjust the test to check for the correct version or configure the tests to install the newest napari version which would work? Maybe introducing a dependency pin like this in the testing configuration would do the trick? [project.optional-dependencies]
testing = [
"tox",
"pytest", # https://docs.pytest.org/en/latest/contents.html
"pytest-cov", # https://pytest-cov.readthedocs.io/en/latest/
"pytest-qt", # https://pytest-qt.readthedocs.io/en/latest/
"napari>=0.6.5",
"pyqt5",
] |
Ok, took me a bit of digging but I think I found the issue that let's tests fail here. Apparently it's a bit deeper in how highlighting is implemented right now 😬 Essentially, highlighting triggers an infinite loop. If you try it manually from the viewer, you experience a noteable lag between the selection click and the point on the biaplotter canvas showing up as highlighted. The loop is this:
|
Thanks for the deep testing @jo-mueller ! I will try to reproduce it and check how to fix it. |
Thank me and the copilot ^^" Also, just a thought: What if we re-write the highlighter into some sort of pciker-selector? Here on the clusters-plotter we could just add the callback to the |
Do you mean like a new kind of selector, with a button in the toolbar? It is a good idea! I mean, it is a bit less smooth to use it, but it also wouldn't lead to unexpected behavior from the user side. |
Jup! I think a lot of the underlying logic would be the same (select, unselect, etc). The cool thing is that we could reuse the already existing signals and still introduce the kind of single-object highlighting we want. For instance, would it be possible to check in the There's probably a lot to be learnt from the Mastodon UI :) |
I wouldn't check inside _colorize() at first, but that should be doable with some signal/slot mechanisms if needed. |
This pull request introduces new functionality to focus the viewer on highlighted objects in the
napari_clusters_plotter
widget, along with utility functions for affine transformations and camera adjustments. The most important changes include adding a signal handler for object highlighting, implementing the logic for focusing on selected objects, and creating reusable affine transformation and camera utilities.New functionality for object highlighting and focusing:
highlighted_changed_signal
to the_on_highlighted_changed
method in_setup_callbacks
. This enables the widget to respond when an object is highlighted. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR186-R189)_on_highlighted_changed
, which focuses the viewer on a highlighted object in the layer. It handles different layer types such asPoints
,Labels
,Surface
,Shapes
, andTracks
. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR752-R948)Utility functions for affine transformations:
_apply_affine_transform
to apply affine transformations to coordinates. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR752-R948)_build_affine_matrix
to construct an affine transformation matrix from rotation, scaling, shearing, and translation components. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR752-R948)Camera utilities for viewer adjustments:
_set_viewer_camera
to adjust the viewer's camera to focus on specified coordinates, including calculating an appropriate zoom level. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR752-R948)_calculate_default_zoom
to compute the default zoom level for the viewer based on the scene size and margin. (src/napari_clusters_plotter/_new_plotter_widget.py
, src/napari_clusters_plotter/_new_plotter_widget.pyR752-R948)To do:
Escape
) condition (reset_view)?