8000 Add optional fixed `length` parameter to scale bar by jo-mueller · Pull Request #7167 · napari/napari · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add optional fixed length parameter to scale bar #7167

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

Merged
merged 22 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3c6ad94
Add `fixed_width` parameter to `ScaleBarOverlay` and `VispyScaleBarOv…
jo-mueller Aug 7, 2024
d3a1312
do rounding only when fixed_width is unset
jo-mueller Aug 7, 2024
bf95e70
code style
jo-mueller Aug 7, 2024
b404824
force fixed_width to `int`
jo-mueller Aug 7, 2024
5750279
added comment for fixed_width usage
jo-mueller Aug 7, 2024
048e9dd
removed setting fixed size in example
jo-mueller Aug 8, 2024
0520ee6
merged testing functionality for fixed width into existing test
jo-mueller Aug 8, 2024
602616c
refactored target_canvas_pixels_rounded variable
jo-mueller Aug 8, 2024
bbb8893
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 8, 2024
92f7aca
Update napari/_vispy/_tests/test_vispy_scale_bar_visual.py
jo-mueller Aug 8, 2024
aa79f2d
change property name from `fixed_width` to `length`
jo-mueller Aug 8, 2024
27dc76b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 8, 2024
064a049
Update napari/components/overlays/scale_bar.py
jo-mueller Aug 8, 2024
2a17fa0
Update napari/components/_tests/test_scale_bar.py
jo-mueller Aug 8, 2024
2677f4d
set length type to float
jo-mueller Aug 8, 2024
b176916
cut length number display to significant digits
jo-mueller Aug 8, 2024
aa30fe8
Update napari/components/_tests/test_scale_bar.py
jo-mueller Aug 8, 2024
34ced1c
set default target length to float
jo-mueller Aug 8, 2024
497122b
set `_target_length` to float
jo-mueller Aug 8, 2024
e1222d3
Merge branch 'main' into add-fixed-width
Czaki Aug 8, 2024
468b509
add scale bar to example script
jo-mueller Aug 9, 2024
0309623
moved scale bar creation up in example
jo-mueller Aug 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/export_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
size = np.array([10, 20, 20])
viewer.add_points(points, size=size)

# Add scale bar of a defined length to the exported figure
viewer.scale_bar.visible = True
viewer.scale_bar.length = 250

# Export figure and change theme before and after exporting to show that the background canvas margins
# are not in the exported figure.
viewer.theme = "light"
Expand Down
5 changes: 4 additions & 1 deletion napari/_vispy/_tests/test_vispy_scale_bar_visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
def test_scale_bar_instantiation(make_napari_viewer):
viewer = make_napari_viewer()
model = ScaleBarOverlay()
VispyScaleBarOverlay(overlay=model, viewer=viewer)
vispy_scale_bar = VispyScaleBarOverlay(overlay=model, viewer=viewer)
assert vispy_scale_bar.overlay.length is None
model.length = 50
assert vispy_scale_bar.overlay.length == 50
31 changes: 21 additions & 10 deletions napari/_vispy/overlays/scale_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class VispyScaleBarOverlay(ViewerOverlayMixin, VispyCanvasOverlay):
"""Scale bar in world coordinates."""

def __init__(self, *, viewer, overlay, parent=None) -> None:
self._target_length = 150
self._target_length = 150.0
self._scale = 1
self._unit: pint.Unit

Expand All @@ -35,6 +35,7 @@ def __init__(self, *, viewer, overlay, parent=None) -> None:
self.overlay.events.font_size.connect(self._on_text_change)
self.overlay.events.ticks.connect(self._on_data_change)
self.overlay.events.unit.connect(self._on_unit_ch 10000 ange)
self.overlay.events.length.connect(self._on_length_change)

self.viewer.events.theme.connect(self._on_data_change)
self.viewer.camera.events.zoom.connect(self._on_zoom_change)
Expand All @@ -45,6 +46,9 @@ def _on_unit_change(self):
self._unit = get_unit_registry()(self.overlay.unit)
self._on_zoom_change(force=True)

def _on_length_change(self):
self._on_zoom_change(force=True)

def _calculate_best_length(
self, desired_length: float
) -> tuple[float, pint.Quantity]:
Expand Down Expand Up @@ -112,18 +116,24 @@ def _on_zoom_change(self, *, force: bool = False):
# convert desired length to world size
target_world_pixels = scale_canvas2world * target_canvas_pixels

# calculate the desired length as well as update the value and units
target_world_pixels_rounded, new_dim = self._calculate_best_length(
target_world_pixels
)
target_canvas_pixels_rounded = (
target_world_pixels_rounded / scale_canvas2world
)
scale = target_canvas_pixels_rounded
# If length is set, use that value to calculate the scale bar length
if self.overlay.length is not None:
target_canvas_pixels = self.overlay.length / scale_canvas2world
new_dim = self.overlay.length * self._unit.units
else:
# calculate the desired length as well as update the value and units
target_world_pixels_rounded, new_dim = self._calculate_best_length(
target_world_pixels
)
target_canvas_pixels = (
target_world_pixels_rounded / scale_canvas2world
)

scale = target_canvas_pixels

# Update scalebar and text
self.node.transform.scale = [scale, 1, 1, 1]
self.node.text.text = f'{new_dim:~}'
self.node.text.text = f'{new_dim:g~#P}'
self.x_size = scale # needed to offset properly
self._on_position_change()

Expand Down Expand Up @@ -171,3 +181,4 @@ def reset(self):
self._on_data_change()
self._on_box_change()
self._on_text_change()
self._on_length_change()
6 changes: 6 additions & 0 deletions napari/components/_tests/test_scale_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ def test_scale_bar():
"""Test creating scale bar object"""
scale_bar = ScaleBarOverlay()
assert scale_bar is not None


def test_scale_bar_fixed_length():
"""Test creating scale bar object with fixed length"""
scale_bar = ScaleBarOverlay(length=50)
assert scale_bar.length == 50
4 changes: 4 additions & 0 deletions napari/components/overlays/scale_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class ScaleBarOverlay(CanvasOverlay):
unit : Optional[str]
Unit to be used by the scale bar. The value can be set
to `None` to display no units.
length : Optional[float]
Fixed length of the scale bar in physical units. If set to `None`,
it is determined automatically based on zoom level.
position : CanvasPosition
The position of the overlay in the canvas.
visible : bool
Expand All @@ -54,3 +57,4 @@ class ScaleBarOverlay(CanvasOverlay):
default_factory=lambda: ColorValue([0, 0, 0, 0.6])
)
unit: Optional[str] = None
length: Optional[float] = None
Loading
0