napari-spatialdata 0.7.2__tar.gz → 0.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/workflows/benchmarks.yml +2 -2
  2. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/workflows/test.yml +1 -1
  3. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.readthedocs.yaml +1 -1
  4. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/PKG-INFO +6 -6
  5. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/README.md +2 -2
  6. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/asv.conf.json +1 -1
  7. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/setup.cfg +3 -3
  8. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_model.py +2 -1
  9. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_scatterwidgets.py +16 -12
  10. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_version.py +3 -3
  11. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/PKG-INFO +6 -6
  12. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/requires.txt +1 -1
  13. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/scm_file_list.json +60 -60
  14. napari_spatialdata-0.7.3/src/napari_spatialdata.egg-info/scm_version.json +8 -0
  15. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/conftest.py +0 -2
  16. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_scatterwidgets.py +2 -2
  17. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_widgets.py +1 -1
  18. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tox.ini +3 -3
  19. napari_spatialdata-0.7.2/src/napari_spatialdata.egg-info/scm_version.json +0 -8
  20. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/BENCHMARK_FAIL_TEMPLATE.md +0 -0
  21. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/dependabot.yml +0 -0
  22. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/release.yml +0 -0
  23. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/workflows/benchmarks_report.yml +0 -0
  24. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.github/workflows/release.yml +0 -0
  25. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.gitignore +0 -0
  26. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.mypy.ini +0 -0
  27. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.napari/DESCRIPTION.md +0 -0
  28. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/.pre-commit-config.yaml +0 -0
  29. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/LICENSE +0 -0
  30. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/MANIFEST.in +0 -0
  31. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/Readme.md +0 -0
  32. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/__init__.py +0 -0
  33. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/benchmark.in +0 -0
  34. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/benchmark.txt +0 -0
  35. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/benchmark_model.py +0 -0
  36. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/benchmarks/benchmark_qt_widget.py +0 -0
  37. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/Makefile +0 -0
  38. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/_static/.gitkeep +0 -0
  39. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/_templates/.gitkeep +0 -0
  40. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/_templates/autosummary/class.rst +0 -0
  41. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/api.md +0 -0
  42. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/changelog.md +0 -0
  43. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/cli.md +0 -0
  44. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/conf.py +0 -0
  45. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/contributing.md +0 -0
  46. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/extensions/typed_returns.py +0 -0
  47. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/index.md +0 -0
  48. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/limitations.md +0 -0
  49. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/make.bat +0 -0
  50. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/notebooks/mibitof_analysis.ipynb +0 -0
  51. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/notebooks/nanostring_analysis.ipynb +0 -0
  52. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/notebooks/scatterwidget.ipynb +0 -0
  53. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/notebooks/scatterwidget_annotation.ipynb +0 -0
  54. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/notebooks/spatialdata.ipynb +0 -0
  55. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/references.bib +0 -0
  56. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/docs/references.md +0 -0
  57. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/examples/spatialdata_empty.py +0 -0
  58. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/examples/spatialdata_visium.py +0 -0
  59. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/pyproject.toml +0 -0
  60. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/__init__.py +0 -0
  61. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/__main__.py +0 -0
  62. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_annotationwidgets.py +0 -0
  63. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_interactive.py +0 -0
  64. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_reader.py +0 -0
  65. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_sdata_widgets.py +0 -0
  66. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_view.py +0 -0
  67. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_viewer.py +0 -0
  68. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/_widgets.py +0 -0
  69. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/constants/__init__.py +0 -0
  70. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/constants/_constants.py +0 -0
  71. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/constants/_pkg_constants.py +0 -0
  72. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/constants/_utils.py +0 -0
  73. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/constants/config.py +0 -0
  74. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/napari.yaml +0 -0
  75. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/resources/exclamation.png +0 -0
  76. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/resources/icons8-home-48.png +0 -0
  77. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/resources/icons8-pencil-drawing-50.png +0 -0
  78. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/resources/icons8-polygon-80.png +0 -0
  79. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/resources/icons8-rectangle-48.png +0 -0
  80. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/utils/__init__.py +0 -0
  81. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/utils/_categoricals_utils.py +0 -0
  82. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/utils/_test_utils.py +0 -0
  83. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/utils/_utils.py +0 -0
  84. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata/utils/_viewer_utils.py +0 -0
  85. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/SOURCES.txt +0 -0
  86. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/dependency_links.txt +0 -0
  87. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/entry_points.txt +0 -0
  88. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/src/napari_spatialdata.egg-info/top_level.txt +0 -0
  89. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/__init__.py +0 -0
  90. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/plots/groundtruth/Images_can_add_element_image.png +0 -0
  91. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/plots/groundtruth/Images_can_add_element_label.png +0 -0
  92. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/plots/groundtruth/Images_can_add_element_multiple.png +0 -0
  93. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_3d_visualization.py +0 -0
  94. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_cli.py +0 -0
  95. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_interactive.py +0 -0
  96. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_spatialdata.py +0 -0
  97. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_utils.py +0 -0
  98. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_view.py +0 -0
  99. {napari_spatialdata-0.7.2 → napari_spatialdata-0.7.3}/tests/test_viewer.py +0 -0
@@ -66,7 +66,7 @@ jobs:
66
66
  - uses: actions/setup-python@v6
67
67
  name: Install Python
68
68
  with:
69
- python-version: "3.11"
69
+ python-version: "3.12"
70
70
  cache-dependency-path: pyproject.toml
71
71
 
72
72
  - uses: tlambert03/setup-qt-libs@v1
@@ -140,7 +140,7 @@ jobs:
140
140
  env:
141
141
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
142
142
  PLATFORM: ${{ matrix.runs-on }}
143
- PYTHON: "3.11"
143
+ PYTHON: "3.12"
144
144
  BACKEND: ${{ matrix.benchmark-name }}
145
145
  RUN_ID: ${{ github.run_id }}
146
146
  TITLE: "[test-bot] Benchmark tests failing"
@@ -24,7 +24,7 @@ jobs:
24
24
  fail-fast: false
25
25
  matrix:
26
26
  platform: [ubuntu-latest, macos-latest] # [ubuntu-latest, windows-latest, macos-latest]
27
- python-version: ["3.11", "3.13"]
27
+ python-version: ["3.12", "3.13", "3.14"]
28
28
 
29
29
  steps:
30
30
  - uses: actions/checkout@v6
@@ -3,7 +3,7 @@ version: 2
3
3
  build:
4
4
  os: ubuntu-22.04
5
5
  tools:
6
- python: "3.11"
6
+ python: "3.12"
7
7
  sphinx:
8
8
  configuration: docs/conf.py
9
9
  fail_on_warning: false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: napari-spatialdata
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Interactive visualization of spatial omics data with napari
5
5
  Home-page: https://github.com/scverse/napari-spatialdata.git
6
6
  Author: giovanni palla
@@ -16,12 +16,12 @@ Classifier: Framework :: napari
16
16
  Classifier: Topic :: Software Development :: Testing
17
17
  Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Operating System :: OS Independent
23
23
  Classifier: License :: OSI Approved :: BSD License
24
- Requires-Python: >=3.11
24
+ Requires-Python: >=3.12
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: anndata>=0.12.0
@@ -78,10 +78,10 @@ Requires-Dist: pydantic>2; extra == "readthedocs"
78
78
  Provides-Extra: pre
79
79
  Requires-Dist: spatialdata>=0.7.3a1; extra == "pre"
80
80
  Provides-Extra: all
81
- Requires-Dist: napari[pyqt5]; extra == "all"
81
+ Requires-Dist: napari[pyqt6]; extra == "all"
82
82
  Dynamic: license-file
83
83
 
84
- ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.png?raw=true)
84
+ ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.svg?raw=true)
85
85
 
86
86
  # napari-spatialdata: interactive exploration and annotation of spatial omics data
87
87
 
@@ -108,7 +108,7 @@ You can install `napari-spatialdata` via [pip]:
108
108
 
109
109
  pip install napari-spatialdata[all]
110
110
 
111
- The `all` command will install the qt bindings `PyQt5`.
111
+ The `all` extra also installs the Qt bindings `PyQt6` (via `napari[pyqt6]`).
112
112
 
113
113
  Napari now also includes multiple triangulation backends. These improve the speed by which a napari 'Shapes' layer gets
114
114
  loaded (this does not improve the speed of editing large numbers of shapes yet!). See also the napari
@@ -1,4 +1,4 @@
1
- ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.png?raw=true)
1
+ ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.svg?raw=true)
2
2
 
3
3
  # napari-spatialdata: interactive exploration and annotation of spatial omics data
4
4
 
@@ -25,7 +25,7 @@ You can install `napari-spatialdata` via [pip]:
25
25
 
26
26
  pip install napari-spatialdata[all]
27
27
 
28
- The `all` command will install the qt bindings `PyQt5`.
28
+ The `all` extra also installs the Qt bindings `PyQt6` (via `napari[pyqt6]`).
29
29
 
30
30
  Napari now also includes multiple triangulation backends. These improve the speed by which a napari 'Shapes' layer gets
31
31
  loaded (this does not improve the speed of editing large numbers of shapes yet!). See also the napari
@@ -35,7 +35,7 @@
35
35
  "show_commit_url": "http://github.com/napari/napari/commit/",
36
36
 
37
37
  // The Pythons you'd like to test against.
38
- "pythons": ["3.11"],
38
+ "pythons": ["3.12"],
39
39
 
40
40
  // The directory (relative to the current directory) to cache the Python
41
41
  // environments in.
@@ -19,16 +19,16 @@ classifiers =
19
19
  Topic :: Software Development :: Testing
20
20
  Programming Language :: Python
21
21
  Programming Language :: Python :: 3
22
- Programming Language :: Python :: 3.11
23
22
  Programming Language :: Python :: 3.12
24
23
  Programming Language :: Python :: 3.13
24
+ Programming Language :: Python :: 3.14
25
25
  Operating System :: OS Independent
26
26
  License :: OSI Approved :: BSD License
27
27
 
28
28
  [options]
29
29
  packages = find:
30
30
  include_package_data = True
31
- python_requires = >=3.11
31
+ python_requires = >=3.12
32
32
  setup_requires = setuptools_scm
33
33
  install_requires =
34
34
  anndata>=0.12.0
@@ -89,7 +89,7 @@ readthedocs =
89
89
  pre =
90
90
  spatialdata>=0.7.3a1
91
91
  all =
92
- napari[pyqt5]
92
+ napari[pyqt6]
93
93
 
94
94
  [options.packages.find]
95
95
  where = src
@@ -136,7 +136,8 @@ class DataModel:
136
136
  except KeyError:
137
137
  raise KeyError(f"Key `{name}` not found in `adata.var_names`.") from None
138
138
 
139
- column = self.adata._get_X(layer=self.adata_layer)[ix]
139
+ X = self.adata.X if self.adata_layer is None else self.adata.layers[self.adata_layer]
140
+ column = X[ix]
140
141
  index = self.adata.obs[[self.instance_key]].set_index(self.instance_key).index
141
142
  return column, self._format_key(name, adata_layer=True), index
142
143
 
@@ -923,11 +923,11 @@ class PlotWidget(GraphicsLayoutWidget):
923
923
  logger.debug("Left press detected")
924
924
 
925
925
  # Get the position of the click in the scene
926
- scene_pos = event.pos()
926
+ scene_pos = self.mapToScene(event.pos())
927
927
 
928
928
  # Check if the click is within the scatter plot view box
929
929
  if not self.scatter_plot.vb.sceneBoundingRect().contains(scene_pos):
930
- logger.debug("Click outside scatter plot view box, scene position: {scene_pos}")
930
+ logger.debug(f"Click outside scatter plot view box, scene position: {scene_pos}")
931
931
  return
932
932
 
933
933
  pen = pg.mkPen(color="gray", width=2)
@@ -938,7 +938,7 @@ class PlotWidget(GraphicsLayoutWidget):
938
938
 
939
939
  if self.drawing:
940
940
 
941
- plot_pos = self.scatter_plot.vb.mapSceneToView(event.pos())
941
+ plot_pos = self.scatter_plot.vb.mapSceneToView(scene_pos)
942
942
 
943
943
  self.current_roi = pg.PolyLineROI(
944
944
  [], closed=True, removable=True, pen=pen, handlePen=handlePen, hoverPen=hoverPen
@@ -946,7 +946,7 @@ class PlotWidget(GraphicsLayoutWidget):
946
946
  self.scatter_plot.addItem(self.current_roi)
947
947
 
948
948
  self.current_points = [(plot_pos.x(), plot_pos.y())]
949
- self.last_pos = (event.pos().x(), event.pos().y())
949
+ self.last_pos = (scene_pos.x(), scene_pos.y())
950
950
 
951
951
  event.accept()
952
952
 
@@ -954,7 +954,7 @@ class PlotWidget(GraphicsLayoutWidget):
954
954
 
955
955
  logger.info("Rectangle")
956
956
 
957
- plot_pos = self.scatter_plot.vb.mapSceneToView(event.pos())
957
+ plot_pos = self.scatter_plot.vb.mapSceneToView(scene_pos)
958
958
  self.current_roi = pg.RectROI(
959
959
  pos=(plot_pos.x(), plot_pos.y()),
960
960
  size=(0, 0),
@@ -979,16 +979,17 @@ class PlotWidget(GraphicsLayoutWidget):
979
979
  if self.drawing and self.current_roi is not None:
980
980
 
981
981
  if self.last_pos is not None:
982
- dist = np.sqrt((event.pos().x() - self.last_pos[0]) ** 2 + (event.pos().y() - self.last_pos[1]) ** 2)
982
+ scene_pos = self.mapToScene(event.pos())
983
+ dist = np.sqrt((scene_pos.x() - self.last_pos[0]) ** 2 + (scene_pos.y() - self.last_pos[1]) ** 2)
983
984
 
984
985
  if dist > self.vertex_add_threshold:
985
986
 
986
- plot_pos = self.scatter_plot.vb.mapSceneToView(event.pos())
987
+ plot_pos = self.scatter_plot.vb.mapSceneToView(scene_pos)
987
988
  self.current_points.append((plot_pos.x(), plot_pos.y()))
988
989
 
989
990
  self.current_roi.setPoints(self.current_points)
990
991
 
991
- self.last_pos = (event.pos().x(), event.pos().y())
992
+ self.last_pos = (scene_pos.x(), scene_pos.y())
992
993
 
993
994
  logger.debug(f"Updated points for PolyLineROI: {self.current_points}")
994
995
 
@@ -996,7 +997,7 @@ class PlotWidget(GraphicsLayoutWidget):
996
997
 
997
998
  elif self.rectangle and self.current_roi is not None and self.initial_pos is not None:
998
999
 
999
- plot_pos = self.scatter_plot.vb.mapSceneToView(event.pos())
1000
+ plot_pos = self.scatter_plot.vb.mapSceneToView(self.mapToScene(event.pos()))
1000
1001
  width = plot_pos.x() - self.initial_pos.x() # type: ignore[attr-defined]
1001
1002
  height = plot_pos.y() - self.initial_pos.y() # type: ignore[attr-defined]
1002
1003
  self.current_roi.setSize([width, height])
@@ -1010,7 +1011,7 @@ class PlotWidget(GraphicsLayoutWidget):
1010
1011
  super().mouseMoveEvent(event)
1011
1012
 
1012
1013
  # Get cursor position
1013
- scene_pos = event.pos()
1014
+ scene_pos = self.mapToScene(event.pos())
1014
1015
  plot_pos = self.scatter_plot.vb.mapSceneToView(scene_pos)
1015
1016
 
1016
1017
  # Update the cursor position label
@@ -1021,7 +1022,10 @@ class PlotWidget(GraphicsLayoutWidget):
1021
1022
 
1022
1023
  def mouseReleaseEvent(self, event: Any) -> None:
1023
1024
 
1024
- logger.debug(f"Mouse release event detected at {self.scatter_plot.vb.mapSceneToView(event.pos())}")
1025
+ # also called by scene().sigMouseClicked with a pyqtgraph MouseClickEvent, whose pos() mapToScene can't take
1026
+ if isinstance(event, QtGui.QMouseEvent):
1027
+ scene_pos = self.mapToScene(event.pos())
1028
+ logger.debug(f"Mouse release event detected at {self.scatter_plot.vb.mapSceneToView(scene_pos)}")
1025
1029
 
1026
1030
  if self.drawing and event.button() == Qt.LeftButton:
1027
1031
 
@@ -1049,7 +1053,7 @@ class PlotWidget(GraphicsLayoutWidget):
1049
1053
  def mouseDoubleClickEvent(self, event: Any) -> None:
1050
1054
  if event.button() == Qt.LeftButton:
1051
1055
 
1052
- plot_pos = self.scatter_plot.vb.mapSceneToView(event.pos())
1056
+ plot_pos = self.scatter_plot.vb.mapSceneToView(self.mapToScene(event.pos()))
1053
1057
  point = Point(plot_pos.x(), plot_pos.y())
1054
1058
 
1055
1059
  self.remove_roi(point=point)
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.7.2'
22
- __version_tuple__ = version_tuple = (0, 7, 2)
21
+ __version__ = version = '0.7.3'
22
+ __version_tuple__ = version_tuple = (0, 7, 3)
23
23
 
24
- __commit_id__ = commit_id = 'ga1150de77'
24
+ __commit_id__ = commit_id = 'g2cb4e2ca7'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: napari-spatialdata
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Interactive visualization of spatial omics data with napari
5
5
  Home-page: https://github.com/scverse/napari-spatialdata.git
6
6
  Author: giovanni palla
@@ -16,12 +16,12 @@ Classifier: Framework :: napari
16
16
  Classifier: Topic :: Software Development :: Testing
17
17
  Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Operating System :: OS Independent
23
23
  Classifier: License :: OSI Approved :: BSD License
24
- Requires-Python: >=3.11
24
+ Requires-Python: >=3.12
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: anndata>=0.12.0
@@ -78,10 +78,10 @@ Requires-Dist: pydantic>2; extra == "readthedocs"
78
78
  Provides-Extra: pre
79
79
  Requires-Dist: spatialdata>=0.7.3a1; extra == "pre"
80
80
  Provides-Extra: all
81
- Requires-Dist: napari[pyqt5]; extra == "all"
81
+ Requires-Dist: napari[pyqt6]; extra == "all"
82
82
  Dynamic: license-file
83
83
 
84
- ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.png?raw=true)
84
+ ![SpatialData banner](https://github.com/scverse/spatialdata/blob/main/docs/_static/img/spatialdata_horizontal.svg?raw=true)
85
85
 
86
86
  # napari-spatialdata: interactive exploration and annotation of spatial omics data
87
87
 
@@ -108,7 +108,7 @@ You can install `napari-spatialdata` via [pip]:
108
108
 
109
109
  pip install napari-spatialdata[all]
110
110
 
111
- The `all` command will install the qt bindings `PyQt5`.
111
+ The `all` extra also installs the Qt bindings `PyQt6` (via `napari[pyqt6]`).
112
112
 
113
113
  Napari now also includes multiple triangulation backends. These improve the speed by which a napari 'Shapes' layer gets
114
114
  loaded (this does not improve the speed of editing large numbers of shapes yet!). See also the napari
@@ -26,7 +26,7 @@ xarray
26
26
  xarray-datatree
27
27
 
28
28
  [all]
29
- napari[pyqt5]
29
+ napari[pyqt6]
30
30
 
31
31
  [bermuda]
32
32
  bermuda
@@ -1,92 +1,92 @@
1
1
  {
2
2
  "files": [
3
+ ".github/BENCHMARK_FAIL_TEMPLATE.md",
4
+ ".github/dependabot.yml",
5
+ ".github/release.yml",
6
+ ".github/workflows/benchmarks.yml",
7
+ ".github/workflows/benchmarks_report.yml",
8
+ ".github/workflows/release.yml",
9
+ ".github/workflows/test.yml",
10
+ ".gitignore",
11
+ ".mypy.ini",
12
+ ".napari/DESCRIPTION.md",
3
13
  ".pre-commit-config.yaml",
4
- "README.md",
5
- "setup.cfg",
6
- "tox.ini",
14
+ ".readthedocs.yaml",
7
15
  "LICENSE",
8
- "pyproject.toml",
9
- "asv.conf.json",
10
- ".mypy.ini",
11
16
  "MANIFEST.in",
12
- ".gitignore",
13
- ".readthedocs.yaml",
14
- ".napari/DESCRIPTION.md",
17
+ "README.md",
18
+ "asv.conf.json",
19
+ "benchmarks/Readme.md",
20
+ "benchmarks/__init__.py",
21
+ "benchmarks/benchmark.in",
22
+ "benchmarks/benchmark.txt",
23
+ "benchmarks/benchmark_model.py",
24
+ "benchmarks/benchmark_qt_widget.py",
15
25
  "docs/Makefile",
26
+ "docs/_static/.gitkeep",
27
+ "docs/_templates/.gitkeep",
28
+ "docs/_templates/autosummary/class.rst",
16
29
  "docs/api.md",
17
- "docs/references.md",
18
- "docs/contributing.md",
19
- "docs/limitations.md",
20
- "docs/make.bat",
21
30
  "docs/changelog.md",
22
31
  "docs/cli.md",
23
- "docs/references.bib",
24
32
  "docs/conf.py",
25
- "docs/index.md",
33
+ "docs/contributing.md",
26
34
  "docs/extensions/typed_returns.py",
27
- "docs/_static/.gitkeep",
28
- "docs/_templates/.gitkeep",
29
- "docs/_templates/autosummary/class.rst",
30
- "docs/notebooks/scatterwidget.ipynb",
31
- "docs/notebooks/scatterwidget_annotation.ipynb",
35
+ "docs/index.md",
36
+ "docs/limitations.md",
37
+ "docs/make.bat",
32
38
  "docs/notebooks/mibitof_analysis.ipynb",
33
39
  "docs/notebooks/nanostring_analysis.ipynb",
40
+ "docs/notebooks/scatterwidget.ipynb",
41
+ "docs/notebooks/scatterwidget_annotation.ipynb",
34
42
  "docs/notebooks/spatialdata.ipynb",
43
+ "docs/references.bib",
44
+ "docs/references.md",
45
+ "examples/spatialdata_empty.py",
46
+ "examples/spatialdata_visium.py",
47
+ "pyproject.toml",
48
+ "setup.cfg",
35
49
  "src/napari_spatialdata/__init__.py",
36
- "src/napari_spatialdata/_reader.py",
50
+ "src/napari_spatialdata/__main__.py",
51
+ "src/napari_spatialdata/_annotationwidgets.py",
37
52
  "src/napari_spatialdata/_interactive.py",
53
+ "src/napari_spatialdata/_model.py",
54
+ "src/napari_spatialdata/_reader.py",
38
55
  "src/napari_spatialdata/_scatterwidgets.py",
56
+ "src/napari_spatialdata/_sdata_widgets.py",
39
57
  "src/napari_spatialdata/_view.py",
40
- "src/napari_spatialdata/_annotationwidgets.py",
41
- "src/napari_spatialdata/_widgets.py",
42
58
  "src/napari_spatialdata/_viewer.py",
43
- "src/napari_spatialdata/_sdata_widgets.py",
44
- "src/napari_spatialdata/_model.py",
45
- "src/napari_spatialdata/__main__.py",
46
- "src/napari_spatialdata/napari.yaml",
47
- "src/napari_spatialdata/resources/icons8-rectangle-48.png",
48
- "src/napari_spatialdata/resources/icons8-home-48.png",
49
- "src/napari_spatialdata/resources/icons8-polygon-80.png",
50
- "src/napari_spatialdata/resources/exclamation.png",
51
- "src/napari_spatialdata/resources/icons8-pencil-drawing-50.png",
52
- "src/napari_spatialdata/constants/_pkg_constants.py",
59
+ "src/napari_spatialdata/_widgets.py",
53
60
  "src/napari_spatialdata/constants/__init__.py",
54
- "src/napari_spatialdata/constants/config.py",
55
61
  "src/napari_spatialdata/constants/_constants.py",
62
+ "src/napari_spatialdata/constants/_pkg_constants.py",
56
63
  "src/napari_spatialdata/constants/_utils.py",
64
+ "src/napari_spatialdata/constants/config.py",
65
+ "src/napari_spatialdata/napari.yaml",
66
+ "src/napari_spatialdata/resources/exclamation.png",
67
+ "src/napari_spatialdata/resources/icons8-home-48.png",
68
+ "src/napari_spatialdata/resources/icons8-pencil-drawing-50.png",
69
+ "src/napari_spatialdata/resources/icons8-polygon-80.png",
70
+ "src/napari_spatialdata/resources/icons8-rectangle-48.png",
57
71
  "src/napari_spatialdata/utils/__init__.py",
72
+ "src/napari_spatialdata/utils/_categoricals_utils.py",
58
73
  "src/napari_spatialdata/utils/_test_utils.py",
59
74
  "src/napari_spatialdata/utils/_utils.py",
60
75
  "src/napari_spatialdata/utils/_viewer_utils.py",
61
- "src/napari_spatialdata/utils/_categoricals_utils.py",
62
76
  "tests/__init__.py",
63
- "tests/test_utils.py",
64
- "tests/test_spatialdata.py",
65
- "tests/test_3d_visualization.py",
66
- "tests/test_widgets.py",
67
- "tests/test_interactive.py",
68
- "tests/test_viewer.py",
69
- "tests/test_view.py",
70
77
  "tests/conftest.py",
71
- "tests/test_cli.py",
72
- "tests/test_scatterwidgets.py",
78
+ "tests/plots/groundtruth/Images_can_add_element_image.png",
73
79
  "tests/plots/groundtruth/Images_can_add_element_label.png",
74
80
  "tests/plots/groundtruth/Images_can_add_element_multiple.png",
75
- "tests/plots/groundtruth/Images_can_add_element_image.png",
76
- "benchmarks/Readme.md",
77
- "benchmarks/__init__.py",
78
- "benchmarks/benchmark_qt_widget.py",
79
- "benchmarks/benchmark_model.py",
80
- "benchmarks/benchmark.in",
81
- "benchmarks/benchmark.txt",
82
- "examples/spatialdata_empty.py",
83
- "examples/spatialdata_visium.py",
84
- ".github/release.yml",
85
- ".github/BENCHMARK_FAIL_TEMPLATE.md",
86
- ".github/dependabot.yml",
87
- ".github/workflows/test.yml",
88
- ".github/workflows/release.yml",
89
- ".github/workflows/benchmarks_report.yml",
90
- ".github/workflows/benchmarks.yml"
81
+ "tests/test_3d_visualization.py",
82
+ "tests/test_cli.py",
83
+ "tests/test_interactive.py",
84
+ "tests/test_scatterwidgets.py",
85
+ "tests/test_spatialdata.py",
86
+ "tests/test_utils.py",
87
+ "tests/test_view.py",
88
+ "tests/test_viewer.py",
89
+ "tests/test_widgets.py",
90
+ "tox.ini"
91
91
  ]
92
92
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.7.3",
3
+ "distance": 0,
4
+ "node": "g2cb4e2ca76b13b2ae53be762007375b875d238bf",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-11-10"
8
+ }
@@ -219,7 +219,6 @@ def adata_shapes() -> AnnData:
219
219
  obsm_shapes = {"spatial": rng.integers(0, blobs.shape[0], size=(n_obs_shapes, 2))}
220
220
  return AnnData(
221
221
  rng.normal(size=(n_obs_shapes, n_var)),
222
- dtype=np.float64,
223
222
  obs=obs_shapes,
224
223
  obsm=obsm_shapes,
225
224
  uns=uns_shapes,
@@ -295,7 +294,6 @@ def generate_adata(n_var: int, obs: pd.DataFrame, obsm: dict[Any, Any], uns: dic
295
294
  obs=obs,
296
295
  obsm=obsm,
297
296
  uns=uns,
298
- dtype=np.float64,
299
297
  )
300
298
 
301
299
 
@@ -182,8 +182,8 @@ def plot_coords_to_viewport(plot_widget, x, y):
182
182
 
183
183
  def send_mouse_event(event_type, widget, pos, button=QtCore.Qt.LeftButton):
184
184
  """Send a mouse event to a widget."""
185
- # necessary because of https://bugreports.qt.io/browse/QTBUG-5232
186
- event = QtGui.QMouseEvent(event_type, pos, button, button, QtCore.Qt.NoModifier)
185
+ # necessary because of https://bugreports.qt.io/browse/QTBUG-5232; Qt6 bindings need a QPointF position
186
+ event = QtGui.QMouseEvent(event_type, QtCore.QPointF(pos), button, button, QtCore.Qt.NoModifier)
187
187
  QtWidgets.QApplication.sendEvent(widget, event)
188
188
 
189
189
 
@@ -316,7 +316,7 @@ def test_old_annotation(adata_labels, annotation_values, mocker):
316
316
  col_name = scatter_widget.model.adata.obs.columns[0]
317
317
  mocker.patch.object(scatter_widget, "open_annotation_dialog", return_value=col_name)
318
318
  mocker.patch.object(scatter_widget.plot_widget, "get_selection", return_value=annotation_values)
319
- mocker.patch("PyQt5.QtWidgets.QMessageBox.question", return_value=QtWidgets.QMessageBox.Yes)
319
+ mocker.patch.object(QtWidgets.QMessageBox, "question", return_value=QtWidgets.QMessageBox.Yes)
320
320
 
321
321
  scatter_widget.export()
322
322
 
@@ -1,11 +1,12 @@
1
1
  [tox]
2
- envlist = py{310,312}-{linux,macos,windows}
2
+ envlist = py{312,313,314}-{linux,macos,windows}
3
3
  isolated_build=true
4
4
 
5
5
  [gh-actions]
6
6
  python =
7
- 3.10: py310
8
7
  3.12: py312
8
+ 3.13: py313
9
+ 3.14: py314
9
10
 
10
11
  [gh-actions:env]
11
12
  PLATFORM =
@@ -24,7 +25,6 @@ deps =
24
25
  pytest-cov
25
26
  pytest-qt
26
27
  pytest-mock
27
- PyQt5
28
28
  passenv =
29
29
  CI
30
30
  GITHUB_ACTIONS
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.7.2",
3
- "distance": 0,
4
- "node": "ga1150de77d9c42467ab0f27b4aa94a048765707e",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-05-15"
8
- }