Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: check-docstring-first
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/psf/black-pre-commit-mirror
rev: 25.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.1
hooks:
- id: black
- id: ruff-format

- repo: https://github.com/tlambert03/napari-plugin-checks
rev: v0.3.0
hooks:
- id: napari-plugin-checks

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
rev: v1.18.2
hooks:
- id: mypy
additional_dependencies: [numpy, matplotlib]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.11.9'
rev: 'v0.13.1'
hooks:
- id: ruff

Expand Down
20 changes: 5 additions & 15 deletions src/napari_matplotlib/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ def _on_napari_theme_changed(self, event: Event) -> None:
event : napari.utils.events.Event
Event that triggered the callback.
"""
self.napari_theme_style_sheet = style_sheet_from_theme(
get_theme(event.value)
)
self.napari_theme_style_sheet = style_sheet_from_theme(get_theme(event.value))
self._replace_toolbar_icons()

def _napari_theme_has_light_bg(self) -> bool:
Expand Down Expand Up @@ -220,9 +218,7 @@ def _setup_callbacks(self) -> None:
# z-step changed in viewer
self.viewer.dims.events.current_step.connect(self._draw)
# Layer selection changed in viewer
self.viewer.layers.selection.events.changed.connect(
self._update_layers
)
self.viewer.layers.selection.events.changed.connect(self._update_layers)

@property
def _valid_layer_selection(self) -> bool:
Expand Down Expand Up @@ -307,9 +303,7 @@ class NapariNavigationToolbar(NavigationToolbar2QT):
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
super().__init__(*args, **kwargs) # type: ignore[no-untyped-call]
self.setIconSize(
from_napari_css_get_size_of(
"QtViewerPushButton", fallback=(28, 28)
)
from_napari_css_get_size_of("QtViewerPushButton", fallback=(28, 28))
)

def _update_buttons_checked(self) -> None:
Expand All @@ -324,15 +318,11 @@ def _update_buttons_checked(self) -> None:
QIcon(os.path.join(icon_dir, "Pan_checked.png"))
)
else:
self._actions["pan"].setIcon(
QIcon(os.path.join(icon_dir, "Pan.png"))
)
self._actions["pan"].setIcon(QIcon(os.path.join(icon_dir, "Pan.png")))
if "zoom" in self._actions:
if self._actions["zoom"].isChecked():
self._actions["zoom"].setIcon(
QIcon(os.path.join(icon_dir, "Zoom_checked.png"))
)
else:
self._actions["zoom"].setIcon(
QIcon(os.path.join(icon_dir, "Zoom.png"))
)
self._actions["zoom"].setIcon(QIcon(os.path.join(icon_dir, "Zoom.png")))
11 changes: 3 additions & 8 deletions src/napari_matplotlib/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,7 @@ def on_update_layers(self) -> None:
"""
super().on_update_layers()
if self._valid_layer_selection:
self.layers[0].events.contrast_limits.connect(
self._update_contrast_lims
)
self.layers[0].events.contrast_limits.connect(self._update_contrast_lims)

if not self.layers:
return
Expand Down Expand Up @@ -170,8 +168,7 @@ def draw(self) -> None:
self.axes.hist(data.ravel(), bins=bins.tolist(), label=layer.name)

self._contrast_lines = [
self.axes.axvline(lim, color="white")
for lim in layer.contrast_limits
self.axes.axvline(lim, color="white") for lim in layer.contrast_limits
]
self.axes.legend()

Expand All @@ -197,9 +194,7 @@ def __init__(
self.layout().addWidget(QLabel("Key:"))
self.layout().addWidget(self._key_selection_widget)

self._key_selection_widget.currentTextChanged.connect(
self._set_axis_keys
)
self._key_selection_widget.currentTextChanged.connect(self._set_axis_keys)

self._update_layers(None)

Expand Down
4 changes: 1 addition & 3 deletions src/napari_matplotlib/tests/scatter/test_scatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ def test_scatter_3D(make_napari_viewer, brain_data):

viewer.add_image(brain_data[0], **brain_data[1], name="brain")

viewer.add_image(
brain_data[0] * -1.0, **brain_data[1], name="brain_reversed"
)
viewer.add_image(brain_data[0] * -1.0, **brain_data[1], name="brain_reversed")
# De-select existing selection
viewer.layers.selection.clear()
axis = viewer.dims.last_used
Expand Down
12 changes: 3 additions & 9 deletions src/napari_matplotlib/tests/scatter/test_scatter_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@


@pytest.mark.mpl_image_compare
def test_features_scatter_widget_2D(
make_napari_viewer, points_with_features_data
):
def test_features_scatter_widget_2D(make_napari_viewer, points_with_features_data):
viewer = make_napari_viewer()
viewer.theme = "light"
widget = FeaturesScatterWidget(viewer)

viewer.add_points(
points_with_features_data[0], **points_with_features_data[1]
)
viewer.add_points(points_with_features_data[0], **points_with_features_data[1])
assert len(viewer.layers) == 1
# De-select existing selection
viewer.layers.selection.clear()
Expand All @@ -33,9 +29,7 @@ def test_features_scatter_widget_2D(
return deepcopy(fig)


def make_labels_layer_with_features() -> (
tuple[npt.NDArray[np.uint16], dict[str, Any]]
):
def make_labels_layer_with_features() -> tuple[npt.NDArray[np.uint16], dict[str, Any]]:
label_image: npt.NDArray[np.uint16] = np.zeros((100, 100), dtype=np.uint16)
for label_value, start_index in enumerate([10, 30, 50], start=1):
end_index = start_index + 10
Expand Down
4 changes: 1 addition & 3 deletions src/napari_matplotlib/tests/test_layer_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ def assert_features_plot_changes(
widget = widget_cls(viewer)
viewer.add_points(data[0], **data[1])
# Change the features data for the second layer
data[1]["features"] = {
name: data + 1 for name, data in data[1]["features"].items()
}
data[1]["features"] = {name: data + 1 for name, data in data[1]["features"].items()}
viewer.add_points(data[0], **data[1])
assert_plot_changes(viewer, widget, n_layers=1)

Expand Down
22 changes: 7 additions & 15 deletions src/napari_matplotlib/tests/test_theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@
"theme_name, expected_icons",
[("dark", "white"), ("light", "black")],
)
def test_theme_mpl_toolbar_icons(
make_napari_viewer, theme_name, expected_icons
):
def test_theme_mpl_toolbar_icons(make_napari_viewer, theme_name, expected_icons):
"""Check that the icons are taken from the correct folder for each napari theme."""
viewer = make_napari_viewer()
viewer.theme = theme_name
path_to_icons = NapariMPLWidget(viewer)._get_path_to_icon()
assert path_to_icons.exists(), "The theme points to non-existant icons."
assert (
path_to_icons.stem == expected_icons
), "The theme is selecting unexpected icons."
assert path_to_icons.stem == expected_icons, (
"The theme is selecting unexpected icons."
)


def _mock_up_theme() -> None:
Expand All @@ -32,9 +30,7 @@ def _mock_up_theme() -> None:
blue_theme = napari.utils.theme.get_theme("dark")
blue_theme.label = "blue"
blue_theme.background = "#4169e1" # my favourite shade of blue
napari.utils.theme.register_theme(
"blue", blue_theme, source="napari-mpl-tests"
)
napari.utils.theme.register_theme("blue", blue_theme, source="napari-mpl-tests")


def test_theme_background_check(make_napari_viewer):
Expand Down Expand Up @@ -62,9 +58,7 @@ def test_theme_background_check(make_napari_viewer):
("light", "#3b3a39"), # #3b3a39 is a brownish dark grey (almost black)
],
)
def test_titles_respect_theme(
make_napari_viewer, theme_name, expected_text_colour
):
def test_titles_respect_theme(make_napari_viewer, theme_name, expected_text_colour):
"""
Test that the axis labels and titles are the correct color for the napari theme.
"""
Expand Down Expand Up @@ -114,9 +108,7 @@ def test_no_theme_side_effects(make_napari_viewer):
ax.hist(normal_dist, bins=100)
ax.set_xlabel("something unrelated to napari (x)")
ax.set_ylabel("something unrelated to napari (y)")
ax.set_title(
"this plot style should not change with napari styles or themes"
)
ax.set_title("this plot style should not change with napari styles or themes")
unrelated_figure.tight_layout()

return unrelated_figure
4 changes: 1 addition & 3 deletions src/napari_matplotlib/tests/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def _are_different(a: QImage, b: QImage) -> bool:
return False


@pytest.mark.parametrize(
"Widget", [HistogramWidget, ScatterWidget, SliceWidget]
)
@pytest.mark.parametrize("Widget", [HistogramWidget, ScatterWidget, SliceWidget])
def test_mpl_toolbar_buttons_checked(make_napari_viewer, Widget):
"""Test that the icons for checkable actions change when when a tool is selected.

Expand Down
5 changes: 2 additions & 3 deletions src/napari_matplotlib/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
def test_version_fallback(mocker):
"""Test the versioning fallback (in case setuptools_scm didn't work)"""
import napari_matplotlib # fmt: skip

assert napari_matplotlib.__version__ != "unknown" # type: ignore[attr-defined]

mocker.patch.dict(sys.modules, {"napari_matplotlib._version": None})
Expand Down Expand Up @@ -70,9 +71,7 @@ def test_fallback_if_missing_dimensions(mocker):
mocker.patch("napari.qt.get_current_stylesheet").return_value = test_css
with pytest.warns(RuntimeWarning, match="Unable to find DimensionToken"):
with pytest.warns(RuntimeWarning, match="Unable to find Flobble"):
assert from_napari_css_get_size_of("Flobble", (1, 2)) == QSize(
1, 2
)
assert from_napari_css_get_size_of("Flobble", (1, 2)) == QSize(1, 2)


def test_fallback_if_prelude_not_in_css():
Expand Down
21 changes: 5 additions & 16 deletions src/napari_matplotlib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,15 @@ def _helper_text(self) -> str | None:
if self.lower is None and self.upper is None:
helper_text = None
elif self.lower is not None and self.upper is None:
helper_text = (
f"Select at least {self.lower} layers to generate plot"
)
helper_text = f"Select at least {self.lower} layers to generate plot"
elif self.lower is None and self.upper is not None:
helper_text = (
f"Select at most {self.upper} layers to generate plot"
)
helper_text = f"Select at most {self.upper} layers to generate plot"
elif self.lower == self.upper:
helper_text = f"Select {self.lower} layers to generate plot"

else:
helper_text = (
f"Select between {self.lower} and "
f"{self.upper} layers to generate plot"
f"Select between {self.lower} and {self.upper} layers to generate plot"
)

if helper_text is not None:
Expand All @@ -80,9 +75,7 @@ def _has_id(nodes: list[tinycss2.ast.Node], id_name: str) -> bool:
"""
Is `id_name` in IdentTokens in the list of CSS `nodes`?
"""
return any(
[node.type == "ident" and node.value == id_name for node in nodes]
)
return any([node.type == "ident" and node.value == id_name for node in nodes])


def _get_dimension(nodes: list[tinycss2.ast.Node], id_name: str) -> int | None:
Expand All @@ -95,11 +88,7 @@ def _get_dimension(nodes: list[tinycss2.ast.Node], id_name: str) -> int | None:
"""
cleaned_nodes = [node for node in nodes if node.type != "whitespace"]
for name, _, value, _ in zip(*(iter(cleaned_nodes),) * 4, strict=False):
if (
name.type == "ident"
and value.type == "dimension"
and name.value == id_name
):
if name.type == "ident" and value.type == "dimension" and name.value == id_name:
return value.int_value
warn(
f"Unable to find DimensionToken for {id_name}",
Expand Down
Loading