roifile 2024.5.24__py3-none-any.whl → 2024.9.15__py3-none-any.whl

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.

Potentially problematic release.


This version of roifile might be problematic. Click here for more details.

roifile/roifile.py CHANGED
@@ -39,7 +39,7 @@ interest, geometric shapes, paths, text, and whatnot for image overlays.
39
39
 
40
40
  :Author: `Christoph Gohlke <https://www.cgohlke.com>`_
41
41
  :License: BSD 3-Clause
42
- :Version: 2024.5.24
42
+ :Version: 2024.9.15
43
43
  :DOI: `10.5281/zenodo.6941603 <https://doi.org/10.5281/zenodo.6941603>`_
44
44
 
45
45
  Quickstart
@@ -65,17 +65,22 @@ Requirements
65
65
  This revision was tested with the following requirements and dependencies
66
66
  (other versions may work):
67
67
 
68
- - `CPython <https://www.python.org>`_ 3.9.13, 3.10.11, 3.11.9, 3.12.3
69
- - `Numpy <https://pypi.org/project/numpy/>`_ 1.26.4
70
- - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.5.22 (optional)
71
- - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.8.4 (optional)
68
+ - `CPython <https://www.python.org>`_ 3.10.11, 3.11.9, 3.12.5, 3.13.0rc2
69
+ - `Numpy <https://pypi.org/project/numpy/>`_ 2.2.1
70
+ - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.8.30 (optional)
71
+ - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.9.2 (optional)
72
72
 
73
73
  Revisions
74
74
  ---------
75
75
 
76
+ 2024.9.15
77
+
78
+ - Improve typing.
79
+ - Deprecate Python 3.9, support Python 3.13.
80
+
76
81
  2024.5.24
77
82
 
78
- - Fix GitHub not correctly rendering docstring examples.
83
+ - Fix docstring examples not correctly rendered on GitHub.
79
84
 
80
85
  2024.3.20
81
86
 
@@ -161,20 +166,47 @@ array([[1.1, 2.2],
161
166
  [5.5, 6.6]], dtype=float32)
162
167
  >>> roi.left, roi.top, roi.right, roi.bottom
163
168
  (1, 2, 7, 8)
169
+ >>> roi2.name = 'test'
164
170
 
165
171
  Plot the ROI using matplotlib:
166
172
 
167
173
  >>> roi.plot()
168
174
 
175
+ Write the ROIs to a ZIP file:
176
+
177
+ >>> roiwrite('_test.zip', [roi, roi2], mode='w')
178
+
179
+ Read the ROIs from the ZIP file:
180
+
181
+ >>> rois = roiread('_test.zip')
182
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
183
+
184
+ Write the ROIs to an ImageJ formatted TIFF file:
185
+
186
+ >>> import tifffile
187
+ >>> tifffile.imwrite(
188
+ ... '_test.tif',
189
+ ... numpy.zeros((9, 9), 'u1'),
190
+ ... imagej=True,
191
+ ... metadata={'Overlays': [roi.tobytes(), roi2.tobytes()]},
192
+ ... )
193
+
194
+ Read the ROIs embedded in an ImageJ formatted TIFF file:
195
+
196
+ >>> rois = roiread('_test.tif')
197
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
198
+
169
199
  View the overlays stored in a ROI, ZIP, or TIFF file from a command line::
170
200
 
171
201
  python -m roifile _test.roi
172
202
 
203
+ For an advanced example, see `roifile_demo.py` in the source distribution.
204
+
173
205
  """
174
206
 
175
207
  from __future__ import annotations
176
208
 
177
- __version__ = '2024.5.24'
209
+ __version__ = '2024.9.15'
178
210
 
179
211
  __all__ = [
180
212
  'roiread',
@@ -201,8 +233,9 @@ import numpy
201
233
 
202
234
  if TYPE_CHECKING:
203
235
  from collections.abc import Iterable
204
- from typing import Any, Literal
236
+ from typing import Any, Iterator, Literal
205
237
 
238
+ from matplotlib.axes import Axes
206
239
  from numpy.typing import ArrayLike, NDArray
207
240
 
208
241
 
@@ -892,15 +925,16 @@ class ImagejRoi:
892
925
 
893
926
  def plot(
894
927
  self,
895
- ax: Any | None = None,
928
+ ax: Axes | None = None,
896
929
  *,
897
930
  rois: Iterable[ImagejRoi] | None = None,
898
931
  title: str | None = None,
899
932
  bounds: bool = False,
900
933
  invert_yaxis: bool | None = None,
901
- **kwargs,
934
+ **kwargs: Any,
902
935
  ) -> None:
903
936
  """Plot a draft of coordinates using matplotlib."""
937
+ fig: Any
904
938
  roitype = self.roitype
905
939
  subtype = self.subtype
906
940
 
@@ -942,8 +976,6 @@ class ImagejRoi:
942
976
  pyplot.show()
943
977
  return
944
978
 
945
- if kwargs is None:
946
- kwargs = {}
947
979
  if 'color' not in kwargs and 'c' not in kwargs:
948
980
  kwargs['color'] = self.hexcolor(self.stroke_color)
949
981
  if 'linewidth' not in kwargs and 'lw' not in kwargs:
@@ -974,7 +1006,8 @@ class ImagejRoi:
974
1006
  if 'fontsize' not in kwargs and self.text_size > 0:
975
1007
  kwargs['fontsize'] = self.text_size
976
1008
  text = ax.text(
977
- *coords[1],
1009
+ coords[1][0],
1010
+ coords[1][1],
978
1011
  self.text,
979
1012
  va='center_baseline',
980
1013
  rotation=self.text_angle,
@@ -1180,17 +1213,37 @@ class ImagejRoi:
1180
1213
  return indent(*info, end='\n)')
1181
1214
 
1182
1215
 
1183
- def scale_text(text: Any, width: float) -> None:
1216
+ def scale_text(
1217
+ text: Any,
1218
+ width: float,
1219
+ *,
1220
+ offset: tuple[float, float] | None = None,
1221
+ ) -> None:
1184
1222
  """Scale matplotlib text to width in data coordinates."""
1185
1223
  from matplotlib.patheffects import AbstractPathEffect
1186
1224
  from matplotlib.transforms import Bbox
1187
1225
 
1188
1226
  class TextScaler(AbstractPathEffect):
1189
- def __init__(self, text, width):
1227
+ def __init__(
1228
+ self,
1229
+ text: Any,
1230
+ width: float,
1231
+ offset: tuple[float, float] | None = None,
1232
+ ) -> None:
1233
+ if offset is None:
1234
+ offset = (0.0, 0.0)
1235
+ super().__init__(offset)
1190
1236
  self._text = text
1191
1237
  self._width = width
1192
1238
 
1193
- def draw_path(self, renderer, gc, tpath, affine, rgbFace=None):
1239
+ def draw_path(
1240
+ self,
1241
+ renderer: Any,
1242
+ gc: Any,
1243
+ tpath: Any,
1244
+ affine: Any,
1245
+ rgbFace: Any = None,
1246
+ ) -> None:
1194
1247
  ax = self._text.axes
1195
1248
  renderer = ax.get_figure().canvas.get_renderer()
1196
1249
  bbox = text.get_window_extent(renderer=renderer)
@@ -1200,7 +1253,7 @@ def scale_text(text: Any, width: float) -> None:
1200
1253
  affine = affine.from_values(scale, 0, 0, scale, 0, 0) + affine
1201
1254
  renderer.draw_path(gc, tpath, affine, rgbFace)
1202
1255
 
1203
- text.set_path_effects([TextScaler(text, width)])
1256
+ text.set_path_effects([TextScaler(text, width, offset)])
1204
1257
 
1205
1258
 
1206
1259
  def oval(rect: ArrayLike, /, points: int = 33) -> NDArray[numpy.float32]:
@@ -1215,9 +1268,9 @@ def oval(rect: ArrayLike, /, points: int = 33) -> NDArray[numpy.float32]:
1215
1268
  return c
1216
1269
 
1217
1270
 
1218
- def indent(*args: Any, sep='', end='') -> str:
1271
+ def indent(*args: Any, sep: str = '', end: str = '') -> str:
1219
1272
  """Return joined string representations of objects with indented lines."""
1220
- text = (sep + '\n').join(
1273
+ text: str = (sep + '\n').join(
1221
1274
  arg if isinstance(arg, str) else repr(arg) for arg in args
1222
1275
  )
1223
1276
  return (
@@ -1256,7 +1309,7 @@ def logger() -> logging.Logger:
1256
1309
  def test(verbose: bool = False) -> None:
1257
1310
  """Test roifile.ImagejRoi class."""
1258
1311
  # test ROIs from a ZIP file
1259
- rois = ImagejRoi.fromfile('tests/ijzip.zip')
1312
+ rois: Any = ImagejRoi.fromfile('tests/ijzip.zip')
1260
1313
  assert isinstance(rois, list)
1261
1314
  assert len(rois) == 7
1262
1315
  for roi in rois:
@@ -1272,7 +1325,7 @@ def test(verbose: bool = False) -> None:
1272
1325
  except OSError:
1273
1326
  pass
1274
1327
 
1275
- def roi_iter():
1328
+ def roi_iter() -> Iterator[ImagejRoi]:
1276
1329
  # issue #9
1277
1330
  yield from rois
1278
1331
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: roifile
3
- Version: 2024.5.24
3
+ Version: 2024.9.15
4
4
  Summary: Read and write ImageJ ROI format
5
5
  Home-page: https://www.cgohlke.com
6
6
  Author: Christoph Gohlke
@@ -15,17 +15,17 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Intended Audience :: Developers
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
- Classifier: Programming Language :: Python :: 3.9
19
18
  Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
22
  Requires-Python: >=3.9
23
23
  Description-Content-Type: text/x-rst
24
24
  License-File: LICENSE
25
25
  Requires-Dist: numpy
26
26
  Provides-Extra: all
27
- Requires-Dist: matplotlib ; extra == 'all'
28
- Requires-Dist: tifffile ; extra == 'all'
27
+ Requires-Dist: matplotlib; extra == "all"
28
+ Requires-Dist: tifffile; extra == "all"
29
29
 
30
30
  Read and write ImageJ ROI format
31
31
  ================================
@@ -38,7 +38,7 @@ interest, geometric shapes, paths, text, and whatnot for image overlays.
38
38
 
39
39
  :Author: `Christoph Gohlke <https://www.cgohlke.com>`_
40
40
  :License: BSD 3-Clause
41
- :Version: 2024.5.24
41
+ :Version: 2024.9.15
42
42
  :DOI: `10.5281/zenodo.6941603 <https://doi.org/10.5281/zenodo.6941603>`_
43
43
 
44
44
  Quickstart
@@ -64,17 +64,22 @@ Requirements
64
64
  This revision was tested with the following requirements and dependencies
65
65
  (other versions may work):
66
66
 
67
- - `CPython <https://www.python.org>`_ 3.9.13, 3.10.11, 3.11.9, 3.12.3
68
- - `Numpy <https://pypi.org/project/numpy/>`_ 1.26.4
69
- - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.5.22 (optional)
70
- - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.8.4 (optional)
67
+ - `CPython <https://www.python.org>`_ 3.10.11, 3.11.9, 3.12.5, 3.13.0rc2
68
+ - `Numpy <https://pypi.org/project/numpy/>`_ 2.2.1
69
+ - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.8.30 (optional)
70
+ - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.9.2 (optional)
71
71
 
72
72
  Revisions
73
73
  ---------
74
74
 
75
+ 2024.9.15
76
+
77
+ - Improve typing.
78
+ - Deprecate Python 3.9, support Python 3.13.
79
+
75
80
  2024.5.24
76
81
 
77
- - Fix GitHub not correctly rendering docstring examples.
82
+ - Fix docstring examples not correctly rendered on GitHub.
78
83
 
79
84
  2024.3.20
80
85
 
@@ -160,11 +165,38 @@ array([[1.1, 2.2],
160
165
  [5.5, 6.6]], dtype=float32)
161
166
  >>> roi.left, roi.top, roi.right, roi.bottom
162
167
  (1, 2, 7, 8)
168
+ >>> roi2.name = 'test'
163
169
 
164
170
  Plot the ROI using matplotlib:
165
171
 
166
172
  >>> roi.plot()
167
173
 
174
+ Write the ROIs to a ZIP file:
175
+
176
+ >>> roiwrite('_test.zip', [roi, roi2], mode='w')
177
+
178
+ Read the ROIs from the ZIP file:
179
+
180
+ >>> rois = roiread('_test.zip')
181
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
182
+
183
+ Write the ROIs to an ImageJ formatted TIFF file:
184
+
185
+ >>> import tifffile
186
+ >>> tifffile.imwrite(
187
+ ... '_test.tif',
188
+ ... numpy.zeros((9, 9), 'u1'),
189
+ ... imagej=True,
190
+ ... metadata={'Overlays': [roi.tobytes(), roi2.tobytes()]},
191
+ ... )
192
+
193
+ Read the ROIs embedded in an ImageJ formatted TIFF file:
194
+
195
+ >>> rois = roiread('_test.tif')
196
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
197
+
168
198
  View the overlays stored in a ROI, ZIP, or TIFF file from a command line::
169
199
 
170
200
  python -m roifile _test.roi
201
+
202
+ For an advanced example, see `roifile_demo.py` in the source distribution.
@@ -0,0 +1,10 @@
1
+ roifile/__init__.py,sha256=leII9J_JWVpi0O9sAnG8s4SpcdwdqEeisFEFsnmN56c,101
2
+ roifile/__main__.py,sha256=Mfn3wm-4cRRChIRonbEcZZT7eRX6RFlS31S8wS1JAVM,132
3
+ roifile/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ roifile/roifile.py,sha256=4DEDDd_hzjhPdrByjDRBYOEzkcjVvg9X3urOOmvStYI,48478
5
+ roifile-2024.9.15.dist-info/LICENSE,sha256=4bDcZTEFGF584Dw8M-07T5qfat7bsrfr8uuffsbFJYU,1559
6
+ roifile-2024.9.15.dist-info/METADATA,sha256=_jKO-ffueSPxsvfJ-b2oTOAA99QgkgI8sTdGe_IMi88,5471
7
+ roifile-2024.9.15.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
8
+ roifile-2024.9.15.dist-info/entry_points.txt,sha256=xP8cwEUbAUeROLXNRanJnAIl13tagbjSSDGfVWf2vh0,49
9
+ roifile-2024.9.15.dist-info/top_level.txt,sha256=QlfLomxPxuYNU0TTR7MXoVBAEAXCj2WJyKvoCJxNwek,8
10
+ roifile-2024.9.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,10 +0,0 @@
1
- roifile/__init__.py,sha256=leII9J_JWVpi0O9sAnG8s4SpcdwdqEeisFEFsnmN56c,101
2
- roifile/__main__.py,sha256=Mfn3wm-4cRRChIRonbEcZZT7eRX6RFlS31S8wS1JAVM,132
3
- roifile/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- roifile/roifile.py,sha256=2SiA7oALORVX0mJC6FfyiHnUxivoU06ptIAp9hmuqrk,47109
5
- roifile-2024.5.24.dist-info/LICENSE,sha256=4bDcZTEFGF584Dw8M-07T5qfat7bsrfr8uuffsbFJYU,1559
6
- roifile-2024.5.24.dist-info/METADATA,sha256=GP9Nj1hx9z3W733mHG8GCBIR257HGOunuhOkqGVkmTo,4639
7
- roifile-2024.5.24.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
- roifile-2024.5.24.dist-info/entry_points.txt,sha256=xP8cwEUbAUeROLXNRanJnAIl13tagbjSSDGfVWf2vh0,49
9
- roifile-2024.5.24.dist-info/top_level.txt,sha256=QlfLomxPxuYNU0TTR7MXoVBAEAXCj2WJyKvoCJxNwek,8
10
- roifile-2024.5.24.dist-info/RECORD,,