roifile 2024.3.20__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.3.20
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,14 +65,23 @@ 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.8, 3.12.2
69
- - `Numpy <https://pypi.org/project/numpy/>`_ 1.26.4
70
- - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.2.12 (optional)
71
- - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.8.3 (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
+
81
+ 2024.5.24
82
+
83
+ - Fix docstring examples not correctly rendered on GitHub.
84
+
76
85
  2024.3.20
77
86
 
78
87
  - Fix writing generator of ROIs (#9).
@@ -157,20 +166,47 @@ array([[1.1, 2.2],
157
166
  [5.5, 6.6]], dtype=float32)
158
167
  >>> roi.left, roi.top, roi.right, roi.bottom
159
168
  (1, 2, 7, 8)
169
+ >>> roi2.name = 'test'
160
170
 
161
171
  Plot the ROI using matplotlib:
162
172
 
163
173
  >>> roi.plot()
164
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
+
165
199
  View the overlays stored in a ROI, ZIP, or TIFF file from a command line::
166
200
 
167
201
  python -m roifile _test.roi
168
202
 
203
+ For an advanced example, see `roifile_demo.py` in the source distribution.
204
+
169
205
  """
170
206
 
171
207
  from __future__ import annotations
172
208
 
173
- __version__ = '2024.3.20'
209
+ __version__ = '2024.9.15'
174
210
 
175
211
  __all__ = [
176
212
  'roiread',
@@ -197,8 +233,9 @@ import numpy
197
233
 
198
234
  if TYPE_CHECKING:
199
235
  from collections.abc import Iterable
200
- from typing import Any, Literal
236
+ from typing import Any, Iterator, Literal
201
237
 
238
+ from matplotlib.axes import Axes
202
239
  from numpy.typing import ArrayLike, NDArray
203
240
 
204
241
 
@@ -888,15 +925,16 @@ class ImagejRoi:
888
925
 
889
926
  def plot(
890
927
  self,
891
- ax: Any | None = None,
928
+ ax: Axes | None = None,
892
929
  *,
893
930
  rois: Iterable[ImagejRoi] | None = None,
894
931
  title: str | None = None,
895
932
  bounds: bool = False,
896
933
  invert_yaxis: bool | None = None,
897
- **kwargs,
934
+ **kwargs: Any,
898
935
  ) -> None:
899
936
  """Plot a draft of coordinates using matplotlib."""
937
+ fig: Any
900
938
  roitype = self.roitype
901
939
  subtype = self.subtype
902
940
 
@@ -938,8 +976,6 @@ class ImagejRoi:
938
976
  pyplot.show()
939
977
  return
940
978
 
941
- if kwargs is None:
942
- kwargs = {}
943
979
  if 'color' not in kwargs and 'c' not in kwargs:
944
980
  kwargs['color'] = self.hexcolor(self.stroke_color)
945
981
  if 'linewidth' not in kwargs and 'lw' not in kwargs:
@@ -970,7 +1006,8 @@ class ImagejRoi:
970
1006
  if 'fontsize' not in kwargs and self.text_size > 0:
971
1007
  kwargs['fontsize'] = self.text_size
972
1008
  text = ax.text(
973
- *coords[1],
1009
+ coords[1][0],
1010
+ coords[1][1],
974
1011
  self.text,
975
1012
  va='center_baseline',
976
1013
  rotation=self.text_angle,
@@ -1176,17 +1213,37 @@ class ImagejRoi:
1176
1213
  return indent(*info, end='\n)')
1177
1214
 
1178
1215
 
1179
- 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:
1180
1222
  """Scale matplotlib text to width in data coordinates."""
1181
1223
  from matplotlib.patheffects import AbstractPathEffect
1182
1224
  from matplotlib.transforms import Bbox
1183
1225
 
1184
1226
  class TextScaler(AbstractPathEffect):
1185
- 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)
1186
1236
  self._text = text
1187
1237
  self._width = width
1188
1238
 
1189
- 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:
1190
1247
  ax = self._text.axes
1191
1248
  renderer = ax.get_figure().canvas.get_renderer()
1192
1249
  bbox = text.get_window_extent(renderer=renderer)
@@ -1196,7 +1253,7 @@ def scale_text(text: Any, width: float) -> None:
1196
1253
  affine = affine.from_values(scale, 0, 0, scale, 0, 0) + affine
1197
1254
  renderer.draw_path(gc, tpath, affine, rgbFace)
1198
1255
 
1199
- text.set_path_effects([TextScaler(text, width)])
1256
+ text.set_path_effects([TextScaler(text, width, offset)])
1200
1257
 
1201
1258
 
1202
1259
  def oval(rect: ArrayLike, /, points: int = 33) -> NDArray[numpy.float32]:
@@ -1211,9 +1268,9 @@ def oval(rect: ArrayLike, /, points: int = 33) -> NDArray[numpy.float32]:
1211
1268
  return c
1212
1269
 
1213
1270
 
1214
- def indent(*args: Any, sep='', end='') -> str:
1271
+ def indent(*args: Any, sep: str = '', end: str = '') -> str:
1215
1272
  """Return joined string representations of objects with indented lines."""
1216
- text = (sep + '\n').join(
1273
+ text: str = (sep + '\n').join(
1217
1274
  arg if isinstance(arg, str) else repr(arg) for arg in args
1218
1275
  )
1219
1276
  return (
@@ -1252,7 +1309,7 @@ def logger() -> logging.Logger:
1252
1309
  def test(verbose: bool = False) -> None:
1253
1310
  """Test roifile.ImagejRoi class."""
1254
1311
  # test ROIs from a ZIP file
1255
- rois = ImagejRoi.fromfile('tests/ijzip.zip')
1312
+ rois: Any = ImagejRoi.fromfile('tests/ijzip.zip')
1256
1313
  assert isinstance(rois, list)
1257
1314
  assert len(rois) == 7
1258
1315
  for roi in rois:
@@ -1268,7 +1325,7 @@ def test(verbose: bool = False) -> None:
1268
1325
  except OSError:
1269
1326
  pass
1270
1327
 
1271
- def roi_iter():
1328
+ def roi_iter() -> Iterator[ImagejRoi]:
1272
1329
  # issue #9
1273
1330
  yield from rois
1274
1331
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: roifile
3
- Version: 2024.3.20
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.3.20
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,14 +64,23 @@ 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.8, 3.12.2
68
- - `Numpy <https://pypi.org/project/numpy/>`_ 1.26.4
69
- - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.2.12 (optional)
70
- - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.8.3 (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
+
80
+ 2024.5.24
81
+
82
+ - Fix docstring examples not correctly rendered on GitHub.
83
+
75
84
  2024.3.20
76
85
 
77
86
  - Fix writing generator of ROIs (#9).
@@ -156,11 +165,38 @@ array([[1.1, 2.2],
156
165
  [5.5, 6.6]], dtype=float32)
157
166
  >>> roi.left, roi.top, roi.right, roi.bottom
158
167
  (1, 2, 7, 8)
168
+ >>> roi2.name = 'test'
159
169
 
160
170
  Plot the ROI using matplotlib:
161
171
 
162
172
  >>> roi.plot()
163
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
+
164
198
  View the overlays stored in a ROI, ZIP, or TIFF file from a command line::
165
199
 
166
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=E2-7K86Bk28V7OL75dNDjxfVF3CPaHfBVpt1mU3MXN4,47036
5
- roifile-2024.3.20.dist-info/LICENSE,sha256=4bDcZTEFGF584Dw8M-07T5qfat7bsrfr8uuffsbFJYU,1559
6
- roifile-2024.3.20.dist-info/METADATA,sha256=qqhZMep2Kjp_DDjC3HYC6tZhsylVxgXguyTGpf92XAc,4566
7
- roifile-2024.3.20.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
- roifile-2024.3.20.dist-info/entry_points.txt,sha256=xP8cwEUbAUeROLXNRanJnAIl13tagbjSSDGfVWf2vh0,49
9
- roifile-2024.3.20.dist-info/top_level.txt,sha256=QlfLomxPxuYNU0TTR7MXoVBAEAXCj2WJyKvoCJxNwek,8
10
- roifile-2024.3.20.dist-info/RECORD,,