roifile 2024.3.20__tar.gz → 2024.9.15__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.

Potentially problematic release.


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

@@ -1,6 +1,15 @@
1
1
  Revisions
2
2
  ---------
3
3
 
4
+ 2024.9.15
5
+
6
+ - Improve typing.
7
+ - Deprecate Python 3.9, support Python 3.13.
8
+
9
+ 2024.5.24
10
+
11
+ - Fix docstring examples not correctly rendered on GitHub.
12
+
4
13
  2024.3.20
5
14
 
6
15
  - Fix writing generator of ROIs (#9).
@@ -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,10 +15,10 @@ 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
@@ -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.
@@ -1,3 +1,6 @@
1
+ ..
2
+ This file is generated by setup.py
3
+
1
4
  Read and write ImageJ ROI format
2
5
  ================================
3
6
 
@@ -9,7 +12,7 @@ interest, geometric shapes, paths, text, and whatnot for image overlays.
9
12
 
10
13
  :Author: `Christoph Gohlke <https://www.cgohlke.com>`_
11
14
  :License: BSD 3-Clause
12
- :Version: 2024.3.20
15
+ :Version: 2024.9.15
13
16
  :DOI: `10.5281/zenodo.6941603 <https://doi.org/10.5281/zenodo.6941603>`_
14
17
 
15
18
  Quickstart
@@ -35,14 +38,23 @@ Requirements
35
38
  This revision was tested with the following requirements and dependencies
36
39
  (other versions may work):
37
40
 
38
- - `CPython <https://www.python.org>`_ 3.9.13, 3.10.11, 3.11.8, 3.12.2
39
- - `Numpy <https://pypi.org/project/numpy/>`_ 1.26.4
40
- - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.2.12 (optional)
41
- - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.8.3 (optional)
41
+ - `CPython <https://www.python.org>`_ 3.10.11, 3.11.9, 3.12.5, 3.13.0rc2
42
+ - `Numpy <https://pypi.org/project/numpy/>`_ 2.2.1
43
+ - `Tifffile <https://pypi.org/project/tifffile/>`_ 2024.8.30 (optional)
44
+ - `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.9.2 (optional)
42
45
 
43
46
  Revisions
44
47
  ---------
45
48
 
49
+ 2024.9.15
50
+
51
+ - Improve typing.
52
+ - Deprecate Python 3.9, support Python 3.13.
53
+
54
+ 2024.5.24
55
+
56
+ - Fix docstring examples not correctly rendered on GitHub.
57
+
46
58
  2024.3.20
47
59
 
48
60
  - Fix writing generator of ROIs (#9).
@@ -101,37 +113,80 @@ Examples
101
113
 
102
114
  Create a new ImagejRoi instance from an array of x, y coordinates:
103
115
 
104
- >>> roi = ImagejRoi.frompoints([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]])
105
- >>> roi.roitype = ROI_TYPE.POINT
106
- >>> roi.options |= ROI_OPTIONS.SHOW_LABELS
116
+ .. code-block:: python
117
+
118
+ >>> roi = ImagejRoi.frompoints([[1.1, 2.2], [3.3, 4.4], [5.5, 6.6]])
119
+ >>> roi.roitype = ROI_TYPE.POINT
120
+ >>> roi.options |= ROI_OPTIONS.SHOW_LABELS
107
121
 
108
122
  Export the instance to an ImageJ ROI formatted byte string or file:
109
123
 
110
- >>> out = roi.tobytes()
111
- >>> out[:4]
112
- b'Iout'
113
- >>> roi.tofile('_test.roi')
124
+ .. code-block:: python
125
+
126
+ >>> out = roi.tobytes()
127
+ >>> out[:4]
128
+ b'Iout'
129
+ >>> roi.tofile('_test.roi')
114
130
 
115
131
  Read the ImageJ ROI from the file and verify the content:
116
132
 
117
- >>> roi2 = ImagejRoi.fromfile('_test.roi')
118
- >>> roi2 == roi
119
- True
120
- >>> roi.roitype == ROI_TYPE.POINT
121
- True
122
- >>> roi.subpixelresolution
123
- True
124
- >>> roi.coordinates()
125
- array([[1.1, 2.2],
126
- [3.3, 4.4],
127
- [5.5, 6.6]], dtype=float32)
128
- >>> roi.left, roi.top, roi.right, roi.bottom
129
- (1, 2, 7, 8)
133
+ .. code-block:: python
134
+
135
+ >>> roi2 = ImagejRoi.fromfile('_test.roi')
136
+ >>> roi2 == roi
137
+ True
138
+ >>> roi.roitype == ROI_TYPE.POINT
139
+ True
140
+ >>> roi.subpixelresolution
141
+ True
142
+ >>> roi.coordinates()
143
+ array([[1.1, 2.2],
144
+ [3.3, 4.4],
145
+ [5.5, 6.6]], dtype=float32)
146
+ >>> roi.left, roi.top, roi.right, roi.bottom
147
+ (1, 2, 7, 8)
148
+ >>> roi2.name = 'test'
130
149
 
131
150
  Plot the ROI using matplotlib:
132
151
 
133
- >>> roi.plot()
152
+ .. code-block:: python
153
+
154
+ >>> roi.plot()
155
+
156
+ Write the ROIs to a ZIP file:
157
+
158
+ .. code-block:: python
159
+
160
+ >>> roiwrite('_test.zip', [roi, roi2], mode='w')
161
+
162
+ Read the ROIs from the ZIP file:
163
+
164
+ .. code-block:: python
165
+
166
+ >>> rois = roiread('_test.zip')
167
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
168
+
169
+ Write the ROIs to an ImageJ formatted TIFF file:
170
+
171
+ .. code-block:: python
172
+
173
+ >>> import tifffile
174
+ >>> tifffile.imwrite(
175
+ ... '_test.tif',
176
+ ... numpy.zeros((9, 9), 'u1'),
177
+ ... imagej=True,
178
+ ... metadata={'Overlays': [roi.tobytes(), roi2.tobytes()]},
179
+ ... )
180
+
181
+ Read the ROIs embedded in an ImageJ formatted TIFF file:
182
+
183
+ .. code-block:: python
184
+
185
+ >>> rois = roiread('_test.tif')
186
+ >>> assert len(rois) == 2 and rois[0] == roi and rois[1].name == 'test'
134
187
 
135
188
  View the overlays stored in a ROI, ZIP, or TIFF file from a command line::
136
189
 
137
190
  python -m roifile _test.roi
191
+
192
+ For an advanced example, see `roifile_demo.py` in the source distribution.
@@ -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,10 +15,10 @@ 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
@@ -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.
@@ -9,11 +9,10 @@ segmentation from/to ImageJ TIFF files.
9
9
 
10
10
  import numpy
11
11
  from matplotlib import pyplot
12
+ from roifile import ImagejRoi
12
13
  from skimage.measure import find_contours, label, regionprops
13
14
  from tifffile import TiffFile, imwrite
14
15
 
15
- from roifile import ImagejRoi
16
-
17
16
 
18
17
  def plot_image_overlays(image, overlays, **kwargs):
19
18
  """Plot image and overlays (bytes) using matplotlib."""
@@ -8,14 +8,32 @@ import sys
8
8
  from setuptools import setup
9
9
 
10
10
 
11
- def search(pattern, code, flags=0):
12
- # return first match for pattern in code
13
- match = re.search(pattern, code, flags)
11
+ def search(pattern, string, flags=0):
12
+ """Return first match of pattern in string."""
13
+ match = re.search(pattern, string, flags)
14
14
  if match is None:
15
15
  raise ValueError(f'{pattern!r} not found')
16
16
  return match.groups()[0]
17
17
 
18
18
 
19
+ def fix_docstring_examples(docstring):
20
+ """Return docstring with examples fixed for GitHub."""
21
+ start = True
22
+ indent = False
23
+ lines = ['..', ' This file is generated by setup.py', '']
24
+ for line in docstring.splitlines():
25
+ if not line.strip():
26
+ start = True
27
+ indent = False
28
+ if line.startswith('>>> '):
29
+ indent = True
30
+ if start:
31
+ lines.extend(['.. code-block:: python', ''])
32
+ start = False
33
+ lines.append((' ' if indent else '') + line)
34
+ return '\n'.join(lines)
35
+
36
+
19
37
  with open('roifile/roifile.py', encoding='utf-8') as fh:
20
38
  code = fh.read().replace('\r\n', '\n').replace('\r', '\n')
21
39
 
@@ -36,7 +54,7 @@ if 'sdist' in sys.argv:
36
54
  # update README, LICENSE, and CHANGES files
37
55
 
38
56
  with open('README.rst', 'w', encoding='utf-8') as fh:
39
- fh.write(readme)
57
+ fh.write(fix_docstring_examples(readme))
40
58
 
41
59
  license = search(
42
60
  r'(# Copyright.*?(?:\r\n|\r|\n))(?:\r\n|\r|\n)+""',
@@ -92,9 +110,9 @@ setup(
92
110
  'Intended Audience :: Developers',
93
111
  'Operating System :: OS Independent',
94
112
  'Programming Language :: Python :: 3 :: Only',
95
- 'Programming Language :: Python :: 3.9',
96
113
  'Programming Language :: Python :: 3.10',
97
114
  'Programming Language :: Python :: 3.11',
98
115
  'Programming Language :: Python :: 3.12',
116
+ 'Programming Language :: Python :: 3.13',
99
117
  ],
100
118
  )
File without changes
File without changes
File without changes