phasorpy 0.4__cp312-cp312-win_arm64.whl → 0.5__cp312-cp312-win_arm64.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.
phasorpy/plot.py CHANGED
@@ -11,14 +11,17 @@ from __future__ import annotations
11
11
  __all__ = [
12
12
  'PhasorPlot',
13
13
  'PhasorPlotFret',
14
+ 'plot_histograms',
15
+ 'plot_image',
14
16
  'plot_phasor',
15
17
  'plot_phasor_image',
16
- 'plot_signal_image',
17
18
  'plot_polar_frequency',
19
+ 'plot_signal_image',
18
20
  ]
19
21
 
20
22
  import math
21
23
  import os
24
+ import warnings
22
25
  from collections.abc import Sequence
23
26
  from typing import TYPE_CHECKING
24
27
 
@@ -75,7 +78,7 @@ class PhasorPlot:
75
78
  Parameters
76
79
  ----------
77
80
  allquadrants : bool, optional
78
- Show all quandrants of phasor space.
81
+ Show all quadrants of phasor space.
79
82
  By default, only the first quadrant with universal semicircle is shown.
80
83
  ax : matplotlib axes, optional
81
84
  Matplotlib axes used for plotting.
@@ -83,7 +86,7 @@ class PhasorPlot:
83
86
  frequency : float, optional
84
87
  Laser pulse or modulation frequency in MHz.
85
88
  grid : bool, optional, default: True
86
- Display polar grid or semicircle.
89
+ Display polar grid or universal semicircle.
87
90
  **kwargs
88
91
  Additional properties to set on `ax`.
89
92
 
@@ -221,7 +224,7 @@ class PhasorPlot:
221
224
  label: Sequence[str] | None = None,
222
225
  **kwargs: Any,
223
226
  ) -> list[Line2D]:
224
- """Plot imag versus real coordinates as markers and/or lines.
227
+ """Plot imaginary versus real coordinates as markers or lines.
225
228
 
226
229
  Parameters
227
230
  ----------
@@ -286,7 +289,7 @@ class PhasorPlot:
286
289
  /,
287
290
  **kwargs: Any,
288
291
  ) -> tuple[NDArray[Any], NDArray[Any], NDArray[Any]]:
289
- """Return 2D histogram of imag versus real coordinates."""
292
+ """Return two-dimensional histogram of imag versus real coordinates."""
290
293
  update_kwargs(kwargs, range=self._limits)
291
294
  (xmin, xmax), (ymin, ymax) = kwargs['range']
292
295
  assert xmax > xmin and ymax > ymin
@@ -319,7 +322,7 @@ class PhasorPlot:
319
322
  /,
320
323
  **kwargs: Any,
321
324
  ) -> None:
322
- """Plot 2D histogram of imag versus real coordinates.
325
+ """Plot two-dimensional histogram of imag versus real coordinates.
323
326
 
324
327
  Parameters
325
328
  ----------
@@ -369,7 +372,9 @@ class PhasorPlot:
369
372
  and :py:meth:`matplotlib.axes.Axes.contour`.
370
373
 
371
374
  """
372
- update_kwargs(kwargs, cmap='Blues', norm='log')
375
+ if 'cmap' not in kwargs and 'colors' not in kwargs:
376
+ kwargs['cmap'] = 'Blues'
377
+ update_kwargs(kwargs, norm='log')
373
378
  kwargs_hist2d = parse_kwargs(
374
379
  kwargs, 'bins', 'range', 'density', 'weights'
375
380
  )
@@ -969,9 +974,9 @@ class PhasorPlotFret(PhasorPlot):
969
974
  acceptor_lifetime : array_like
970
975
  Lifetime of acceptor in ns.
971
976
  fret_efficiency : array_like, optional, default 0
972
- FRET efficiency in range [0..1].
973
- donor_freting : array_like, optional, default 1
974
- Fraction of donors participating in FRET. Range [0..1].
977
+ FRET efficiency in range [0, 1].
978
+ donor_fretting : array_like, optional, default 1
979
+ Fraction of donors participating in FRET. Range [0, 1].
975
980
  donor_bleedthrough : array_like, optional, default 0
976
981
  Weight of donor fluorescence in acceptor channel
977
982
  relative to fluorescence of fully sensitized acceptor.
@@ -1022,7 +1027,7 @@ class PhasorPlotFret(PhasorPlot):
1022
1027
  _donor_lifetime_slider: Slider
1023
1028
  _acceptor_lifetime_slider: Slider
1024
1029
  _fret_efficiency_slider: Slider
1025
- _donor_freting_slider: Slider
1030
+ _donor_fretting_slider: Slider
1026
1031
  _donor_bleedthrough_slider: Slider
1027
1032
  _acceptor_bleedthrough_slider: Slider
1028
1033
  _acceptor_background_slider: Slider
@@ -1053,7 +1058,7 @@ class PhasorPlotFret(PhasorPlot):
1053
1058
  donor_lifetime: float = 4.2,
1054
1059
  acceptor_lifetime: float = 3.0,
1055
1060
  fret_efficiency: float = 0.5,
1056
- donor_freting: float = 1.0,
1061
+ donor_fretting: float = 1.0,
1057
1062
  donor_bleedthrough: float = 0.0,
1058
1063
  acceptor_bleedthrough: float = 0.0,
1059
1064
  acceptor_background: float = 0.0,
@@ -1103,7 +1108,7 @@ class PhasorPlotFret(PhasorPlot):
1103
1108
  frequency,
1104
1109
  donor_lifetime,
1105
1110
  fret_efficiency=self._fret_efficiencies,
1106
- donor_freting=donor_freting,
1111
+ donor_fretting=donor_fretting,
1107
1112
  donor_background=donor_background,
1108
1113
  background_real=background_real,
1109
1114
  background_imag=background_imag,
@@ -1116,7 +1121,7 @@ class PhasorPlotFret(PhasorPlot):
1116
1121
  donor_lifetime,
1117
1122
  acceptor_lifetime,
1118
1123
  fret_efficiency=self._fret_efficiencies,
1119
- donor_freting=donor_freting,
1124
+ donor_fretting=donor_fretting,
1120
1125
  donor_bleedthrough=donor_bleedthrough,
1121
1126
  acceptor_bleedthrough=acceptor_bleedthrough,
1122
1127
  acceptor_background=acceptor_background,
@@ -1135,7 +1140,7 @@ class PhasorPlotFret(PhasorPlot):
1135
1140
  )
1136
1141
  self._acceptor_semicircle_line = lines[0]
1137
1142
 
1138
- if donor_freting < 1.0 and donor_background == 0.0:
1143
+ if donor_fretting < 1.0 and donor_background == 0.0:
1139
1144
  lines = self.line(
1140
1145
  [donor_real, donor_fret_real],
1141
1146
  [donor_imag, donor_fret_imag],
@@ -1285,18 +1290,18 @@ class PhasorPlotFret(PhasorPlot):
1285
1290
  )
1286
1291
  self._fret_efficiency_slider.on_changed(self._on_changed)
1287
1292
 
1288
- self._donor_freting_slider = Slider(
1293
+ self._donor_fretting_slider = Slider(
1289
1294
  ax=axes[6],
1290
- label='Donors FRETing ',
1295
+ label='Donors fretting ',
1291
1296
  valfmt=' %.2f',
1292
1297
  valmin=0.0,
1293
1298
  valmax=1.0,
1294
1299
  valstep=0.01,
1295
- valinit=donor_freting,
1300
+ valinit=donor_fretting,
1296
1301
  # facecolor='tab:green',
1297
1302
  handle_style={'edgecolor': 'tab:green'},
1298
1303
  )
1299
- self._donor_freting_slider.on_changed(self._on_changed)
1304
+ self._donor_fretting_slider.on_changed(self._on_changed)
1300
1305
 
1301
1306
  self._donor_bleedthrough_slider = Slider(
1302
1307
  ax=axes[5],
@@ -1398,7 +1403,7 @@ class PhasorPlotFret(PhasorPlot):
1398
1403
  donor_lifetime = self._donor_lifetime_slider.val
1399
1404
  acceptor_lifetime = self._acceptor_lifetime_slider.val
1400
1405
  fret_efficiency = self._fret_efficiency_slider.val
1401
- donor_freting = self._donor_freting_slider.val
1406
+ donor_fretting = self._donor_fretting_slider.val
1402
1407
  donor_bleedthrough = self._donor_bleedthrough_slider.val
1403
1408
  acceptor_bleedthrough = self._acceptor_bleedthrough_slider.val
1404
1409
  acceptor_background = self._acceptor_background_slider.val
@@ -1420,7 +1425,7 @@ class PhasorPlotFret(PhasorPlot):
1420
1425
  frequency,
1421
1426
  donor_lifetime,
1422
1427
  fret_efficiency=self._fret_efficiencies,
1423
- donor_freting=donor_freting,
1428
+ donor_fretting=donor_fretting,
1424
1429
  donor_background=donor_background,
1425
1430
  background_real=background_real,
1426
1431
  background_imag=background_imag,
@@ -1433,7 +1438,7 @@ class PhasorPlotFret(PhasorPlot):
1433
1438
  donor_lifetime,
1434
1439
  acceptor_lifetime,
1435
1440
  fret_efficiency=self._fret_efficiencies,
1436
- donor_freting=donor_freting,
1441
+ donor_fretting=donor_fretting,
1437
1442
  donor_bleedthrough=donor_bleedthrough,
1438
1443
  acceptor_bleedthrough=acceptor_bleedthrough,
1439
1444
  acceptor_background=acceptor_background,
@@ -1449,7 +1454,7 @@ class PhasorPlotFret(PhasorPlot):
1449
1454
  else:
1450
1455
  self._donor_background_line.set_data([0.0, 0.0], [0.0, 0.0])
1451
1456
 
1452
- if donor_freting < 1.0 and donor_background == 0.0:
1457
+ if donor_fretting < 1.0 and donor_background == 0.0:
1453
1458
  self._donor_donor_line.set_data(
1454
1459
  [donor_real, donor_fret_real],
1455
1460
  [donor_imag, donor_fret_imag],
@@ -1719,7 +1724,7 @@ def plot_phasor_image(
1719
1724
  percentile : float, optional
1720
1725
  The (q, 100-q) percentiles of image data are covered by colormaps.
1721
1726
  By default, the complete value range of `mean` is covered,
1722
- for `real` and `imag` the range [-1..1].
1727
+ for `real` and `imag` the range [-1, 1].
1723
1728
  title : str, optional
1724
1729
  Figure title.
1725
1730
  show : bool, optional, default: True
@@ -1862,6 +1867,7 @@ def plot_signal_image(
1862
1867
  axis: int | str | None = None,
1863
1868
  percentile: float | Sequence[float] | None = None,
1864
1869
  title: str | None = None,
1870
+ xlabel: str | None = None,
1865
1871
  show: bool = True,
1866
1872
  **kwargs: Any,
1867
1873
  ) -> None:
@@ -1884,9 +1890,11 @@ def plot_signal_image(
1884
1890
  percentile : float or [float, float], optional
1885
1891
  The [q, 100-q] percentiles of image data are covered by colormaps.
1886
1892
  By default, the complete value range of `mean` is covered,
1887
- for `real` and `imag` the range [-1..1].
1893
+ for `real` and `imag` the range [-1, 1].
1888
1894
  title : str, optional
1889
1895
  Figure title.
1896
+ xlabel : str, optional
1897
+ Label of axis over which phasor coordinates would be computed.
1890
1898
  show : bool, optional, default: True
1891
1899
  Display figure.
1892
1900
  **kwargs
@@ -1941,6 +1949,11 @@ def plot_signal_image(
1941
1949
  ax.set_title(f'{axis=}')
1942
1950
  ax.plot(numpy.nanmean(signal, axis=tuple(axes)))
1943
1951
 
1952
+ ax.set_ylim(kwargs.get('vmin', None), kwargs.get('vmax', None))
1953
+
1954
+ if xlabel is not None:
1955
+ ax.set_xlabel(xlabel)
1956
+
1944
1957
  # image
1945
1958
  axes = list(sorted(axes[:-2] + [axis]))
1946
1959
  ax = fig.add_subplot(gs[0, 0])
@@ -1950,7 +1963,159 @@ def plot_signal_image(
1950
1963
  percentile=percentile,
1951
1964
  shrink=0.5,
1952
1965
  title='mean',
1966
+ **kwargs,
1967
+ )
1968
+
1969
+ if show:
1970
+ pyplot.show()
1971
+
1972
+
1973
+ def plot_image(
1974
+ *images: ArrayLike,
1975
+ percentile: float | None = None,
1976
+ columns: int | None = None,
1977
+ title: str | None = None,
1978
+ labels: Sequence[str | None] | None = None,
1979
+ show: bool = True,
1980
+ **kwargs: Any,
1981
+ ) -> None:
1982
+ """Plot images.
1983
+
1984
+ Parameters
1985
+ ----------
1986
+ *images : array_like
1987
+ Images to be plotted. Must be two or more dimensional.
1988
+ The last two axes are assumed to be the image axes.
1989
+ Other axes are averaged for display.
1990
+ Three-dimensional images with last axis size of three or four
1991
+ are plotted as RGB(A) images.
1992
+ percentile : float, optional
1993
+ The (q, 100-q) percentiles of image data are covered by colormaps.
1994
+ By default, the complete value range is covered.
1995
+ Does not apply to RGB images.
1996
+ columns : int, optional
1997
+ Number of columns in figure.
1998
+ By default, up to four columns are used.
1999
+ title : str, optional
2000
+ Figure title.
2001
+ labels : sequence of str, optional
2002
+ Labels for each image.
2003
+ show : bool, optional, default: True
2004
+ Display figure.
2005
+ **kwargs
2006
+ Additional arguments passed to :func:`matplotlib.pyplot.imshow`.
2007
+
2008
+ Raises
2009
+ ------
2010
+ ValueError
2011
+ Percentile is out of range.
2012
+
2013
+ """
2014
+ update_kwargs(
2015
+ kwargs, interpolation='nearest', location='right', shrink=0.5
1953
2016
  )
2017
+ cmap = kwargs.pop('cmap', None)
2018
+ figsize = kwargs.pop('figsize', None)
2019
+ subplot_kw = kwargs.pop('subplot_kw', {})
2020
+ location = kwargs['location']
2021
+ allrgb = True
2022
+
2023
+ arrays = []
2024
+ shape = [1, 1]
2025
+ for image in images:
2026
+ image = numpy.asarray(image)
2027
+ if image.ndim < 2:
2028
+ raise ValueError(f'not an image {image.ndim=} < 2')
2029
+ if image.ndim == 3 and image.shape[2] in {3, 4}:
2030
+ # RGB(A)
2031
+ pass
2032
+ else:
2033
+ allrgb = False
2034
+ image = image.reshape(-1, *image.shape[-2:])
2035
+ if image.shape[0] == 1:
2036
+ image = image[0]
2037
+ else:
2038
+ with warnings.catch_warnings():
2039
+ warnings.filterwarnings('ignore', category=RuntimeWarning)
2040
+ image = numpy.nanmean(image, axis=0)
2041
+ assert isinstance(image, numpy.ndarray)
2042
+ for i in (-1, -2):
2043
+ if image.shape[i] > shape[i]:
2044
+ shape[i] = image.shape[i]
2045
+ arrays.append(image)
2046
+
2047
+ if columns is None:
2048
+ n = len(arrays)
2049
+ if n < 3:
2050
+ columns = n
2051
+ elif n < 5:
2052
+ columns = 2
2053
+ elif n < 7:
2054
+ columns = 3
2055
+ else:
2056
+ columns = 4
2057
+ rows = int(numpy.ceil(len(arrays) / columns))
2058
+
2059
+ vmin = None
2060
+ vmax = None
2061
+ if percentile is None:
2062
+ vmin = kwargs.pop('vmin', None)
2063
+ vmax = kwargs.pop('vmax', None)
2064
+ if vmin is None:
2065
+ vmin = numpy.inf
2066
+ for image in images:
2067
+ vmin = min(vmin, numpy.nanmin(image))
2068
+ if vmin == numpy.inf:
2069
+ vmin = None
2070
+ if vmax is None:
2071
+ vmax = -numpy.inf
2072
+ for image in images:
2073
+ vmax = max(vmax, numpy.nanmax(image))
2074
+ if vmax == -numpy.inf:
2075
+ vmax = None
2076
+
2077
+ # create figure with size depending on image aspect
2078
+ fig = pyplot.figure(layout='constrained', figsize=figsize)
2079
+ if figsize is None:
2080
+ # TODO: find optimal figure height as a function of
2081
+ # number of rows and columns, image shapes, labels, and colorbar
2082
+ # presence and placements.
2083
+ if allrgb:
2084
+ hadd = 0.0
2085
+ elif location == 'right':
2086
+ hadd = 0.5
2087
+ else:
2088
+ hadd = 1.2
2089
+ if labels is not None:
2090
+ hadd += 0.3 * rows
2091
+ w, h = fig.get_size_inches()
2092
+ aspect = min(1.0, max(0.5, shape[0] / shape[1]))
2093
+ fig.set_size_inches(
2094
+ w, h * 0.9 / columns * aspect * rows + h * 0.1 * aspect + hadd
2095
+ )
2096
+ gs = GridSpec(rows, columns, figure=fig)
2097
+ if title:
2098
+ fig.suptitle(title)
2099
+
2100
+ axs = []
2101
+ for i, image in enumerate(arrays):
2102
+ ax = fig.add_subplot(gs[i // columns, i % columns], **subplot_kw)
2103
+ ax.set_anchor('C')
2104
+ axs.append(ax)
2105
+ pos = _imshow(
2106
+ ax,
2107
+ image,
2108
+ percentile=percentile,
2109
+ vmin=vmin,
2110
+ vmax=vmax,
2111
+ cmap=cmap,
2112
+ colorbar=percentile is not None,
2113
+ axis=i == 0 and not subplot_kw,
2114
+ title=None if labels is None else labels[i],
2115
+ **kwargs,
2116
+ )
2117
+ if not allrgb and percentile is None:
2118
+ fig.colorbar(pos, ax=axs, shrink=kwargs['shrink'], location=location)
1954
2119
 
1955
2120
  if show:
1956
2121
  pyplot.show()
@@ -2018,6 +2183,58 @@ def plot_polar_frequency(
2018
2183
  pyplot.show()
2019
2184
 
2020
2185
 
2186
+ def plot_histograms(
2187
+ *data: ArrayLike,
2188
+ title: str | None = None,
2189
+ xlabel: str | None = None,
2190
+ ylabel: str | None = None,
2191
+ labels: Sequence[str] | None = None,
2192
+ show: bool = True,
2193
+ **kwargs: Any,
2194
+ ) -> None:
2195
+ """Plot histograms of flattened data arrays.
2196
+
2197
+ Parameters
2198
+ ----------
2199
+ data: array_like
2200
+ Data arrays to be plotted as histograms.
2201
+ title : str, optional
2202
+ Figure title.
2203
+ xlabel : str, optional
2204
+ Label for x-axis.
2205
+ ylabel : str, optional
2206
+ Label for y-axis.
2207
+ labels: sequence of str, optional
2208
+ Labels for each data array.
2209
+ show : bool, optional, default: True
2210
+ Display figure.
2211
+ **kwargs
2212
+ Additional arguments passed to :func:`matplotlib.pyplot.hist`.
2213
+
2214
+ """
2215
+ ax = pyplot.subplots()[1]
2216
+ if kwargs.get('alpha') is None:
2217
+ ax.hist(
2218
+ [numpy.asarray(d).flatten() for d in data], label=labels, **kwargs
2219
+ )
2220
+ else:
2221
+ for d, label in zip(
2222
+ data, [None] * len(data) if labels is None else labels
2223
+ ):
2224
+ ax.hist(numpy.asarray(d).flatten(), label=label, **kwargs)
2225
+ if title is not None:
2226
+ ax.set_title(title)
2227
+ if xlabel is not None:
2228
+ ax.set_xlabel(xlabel)
2229
+ if ylabel is not None:
2230
+ ax.set_ylabel(ylabel)
2231
+ if labels is not None:
2232
+ ax.legend()
2233
+ pyplot.tight_layout()
2234
+ if show:
2235
+ pyplot.show()
2236
+
2237
+
2021
2238
  def _imshow(
2022
2239
  ax: Axes,
2023
2240
  image: NDArray[Any],
@@ -2038,6 +2255,13 @@ def _imshow(
2038
2255
 
2039
2256
  """
2040
2257
  update_kwargs(kwargs, interpolation='none')
2258
+ location = kwargs.pop('location', 'bottom')
2259
+ if image.ndim == 3 and image.shape[2] in {3, 4}:
2260
+ # RGB(A)
2261
+ vmin = None
2262
+ vmax = None
2263
+ percentile = None
2264
+ colorbar = False
2041
2265
  if percentile is not None:
2042
2266
  if isinstance(percentile, Sequence):
2043
2267
  percentile = percentile[0], percentile[1]
@@ -2050,7 +2274,7 @@ def _imshow(
2050
2274
  or percentile[1] > 100
2051
2275
  ):
2052
2276
  raise ValueError(f'{percentile=} out of range')
2053
- vmin, vmax = numpy.percentile(image, percentile)
2277
+ vmin, vmax = numpy.nanpercentile(image, percentile)
2054
2278
  pos = ax.imshow(image, vmin=vmin, vmax=vmax, **kwargs)
2055
2279
  if colorbar:
2056
2280
  if percentile is not None and vmin is not None and vmax is not None:
@@ -2061,7 +2285,7 @@ def _imshow(
2061
2285
  if fig is not None:
2062
2286
  if shrink is None:
2063
2287
  shrink = 0.8
2064
- fig.colorbar(pos, shrink=shrink, location='bottom', ticks=ticks)
2288
+ fig.colorbar(pos, shrink=shrink, location=location, ticks=ticks)
2065
2289
  if title:
2066
2290
  ax.set_title(title)
2067
2291
  if not axis:
phasorpy/utils.py CHANGED
@@ -104,7 +104,7 @@ def spectral_vector_denoise(
104
104
  .. [4] Harman RC, Lang RT, Kercher EM, Leven P, and Spring BQ.
105
105
  `Denoising multiplexed microscopy images in n-dimensional spectral space
106
106
  <https://doi.org/10.1364/BOE.463979>`_.
107
- *Biomedical Optics Express*, 13(8): 4298-4309 (2022)
107
+ *Biomed Opt Express*, 13(8): 4298-4309 (2022)
108
108
 
109
109
  Examples
110
110
  --------
@@ -201,7 +201,7 @@ def anscombe_transformation(
201
201
 
202
202
  Parameters
203
203
  ----------
204
- data: array_like
204
+ data : array_like
205
205
  Noisy Poisson-distributed data to be transformed.
206
206
  **kwargs
207
207
  Optional `arguments passed to numpy universal functions
@@ -250,9 +250,9 @@ def anscombe_transformation_inverse(
250
250
 
251
251
  Parameters
252
252
  ----------
253
- data: array_like
253
+ data : array_like
254
254
  Anscombe-transformed data.
255
- approx: bool, default: False
255
+ approx : bool, default: False
256
256
  If true, return approximation of exact unbiased inverse.
257
257
  **kwargs
258
258
  Optional `arguments passed to numpy universal functions
@@ -288,13 +288,13 @@ def anscombe_transformation_inverse(
288
288
  `A closed-form approximation of the exact unbiased inverse of the
289
289
  Anscombe variance-stabilizing transformation
290
290
  <https://doi.org/10.1109/TIP.2011.2121085>`_.
291
- IEEE Trans Image Process, 20(9): 2697-8 (2011).
291
+ *IEEE Trans Image Process*, 20(9): 2697-8 (2011).
292
292
 
293
293
  .. [3] Makitalo M, and Foi A
294
294
  `Optimal inversion of the generalized Anscombe transformation for
295
295
  Poisson-Gaussian noise
296
296
  <https://doi.org/10.1109/TIP.2012.2202675>`_,
297
- IEEE Trans Image Process, 22(1): 91-103 (2013)
297
+ *IEEE Trans Image Process*, 22(1): 91-103 (2013)
298
298
 
299
299
  Examples
300
300
  --------
@@ -317,7 +317,7 @@ def number_threads(
317
317
  max_threads: int | None = None,
318
318
  /,
319
319
  ) -> int:
320
- """Return number of threads for parallel computations on CPU cores.
320
+ """Return number of threads for parallel computations across CPU cores.
321
321
 
322
322
  This function is used to parse ``num_threads`` parameters.
323
323
 
@@ -332,6 +332,11 @@ def number_threads(
332
332
  max_threads : int, optional
333
333
  Maximum number of threads to return.
334
334
 
335
+ Returns
336
+ -------
337
+ int
338
+ Number of threads for parallel computations.
339
+
335
340
  Examples
336
341
  --------
337
342
  >>> number_threads()
phasorpy/version.py CHANGED
@@ -1,24 +1,32 @@
1
- """Version information."""
1
+ """Version information for PhasorPy and dependencies."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = '0.4'
5
+ __all__ = ['__version__', 'versions']
6
+
7
+ __version__ = '0.5'
6
8
 
7
9
 
8
10
  def versions(
9
11
  *, sep: str = '\n', dash: str = '-', verbose: bool = False
10
12
  ) -> str:
11
- """Return versions of installed packages that phasorpy depends on.
13
+ """Return version information for PhasorPy and its dependencies.
12
14
 
13
15
  Parameters
14
16
  ----------
15
17
  sep : str, optional
16
- Separator between version items. The default is a newline character.
18
+ Separator between version items. Defaults to newline.
17
19
  dash : str, optional
18
- Separator between module name and version.
20
+ Separator between module name and version. Defaults to dash.
19
21
  verbose : bool, optional
20
22
  Include paths to Python interpreter and modules.
21
23
 
24
+ Returns
25
+ -------
26
+ str
27
+ Formatted string containing version information.
28
+ Format: "<package><dash><version>[<space>(<path>)]<sep>"
29
+
22
30
  Example
23
31
  -------
24
32
  >>> print(versions())
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: phasorpy
3
- Version: 0.4
3
+ Version: 0.5
4
4
  Summary: Analysis of fluorescence lifetime and hyperspectral images using the phasor approach
5
5
  Author: PhasorPy Contributors
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://www.phasorpy.org
8
8
  Project-URL: Documentation, https://www.phasorpy.org/docs/stable/
9
9
  Project-URL: Download, https://pypi.org/project/phasorpy/#files
@@ -13,25 +13,24 @@ Project-URL: Release notes, https://www.phasorpy.org/docs/stable/release
13
13
  Classifier: Development Status :: 3 - Alpha
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Intended Audience :: Science/Research
16
- Classifier: License :: OSI Approved :: MIT License
17
16
  Classifier: Programming Language :: Python
18
17
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
18
  Classifier: Operating System :: OS Independent
20
19
  Classifier: Programming Language :: Python :: 3
21
20
  Classifier: Programming Language :: Python :: 3 :: Only
22
- Classifier: Programming Language :: Python :: 3.10
23
21
  Classifier: Programming Language :: Python :: 3.11
24
22
  Classifier: Programming Language :: Python :: 3.12
25
23
  Classifier: Programming Language :: Python :: 3.13
26
- Requires-Python: >=3.10
24
+ Requires-Python: >=3.11
27
25
  Description-Content-Type: text/markdown
28
26
  License-File: LICENSE.txt
29
- Requires-Dist: numpy>=1.24.0
30
- Requires-Dist: matplotlib>=3.7.0
27
+ Requires-Dist: numpy>=1.25.0
28
+ Requires-Dist: matplotlib>=3.8.0
31
29
  Requires-Dist: scipy>=1.11.0
32
30
  Requires-Dist: click
33
31
  Requires-Dist: pooch
34
32
  Requires-Dist: tqdm
33
+ Requires-Dist: scikit-learn>=1.5.0
35
34
  Requires-Dist: xarray>=2023.4.0
36
35
  Requires-Dist: tifffile>=2024.8.30
37
36
  Provides-Extra: docs
@@ -42,17 +41,13 @@ Requires-Dist: sphinx-copybutton; extra == "docs"
42
41
  Requires-Dist: sphinx_click; extra == "docs"
43
42
  Requires-Dist: pydata-sphinx-theme>=0.16.0; extra == "docs"
44
43
  Requires-Dist: numpydoc; extra == "docs"
45
- Provides-Extra: test
46
- Requires-Dist: pytest; extra == "test"
47
- Requires-Dist: pytest-cov; extra == "test"
48
- Requires-Dist: pytest-runner; extra == "test"
49
- Requires-Dist: pytest-doctestplus; extra == "test"
50
- Requires-Dist: coverage; extra == "test"
51
44
  Provides-Extra: all
52
45
  Requires-Dist: lfdfiles>=2024.5.24; extra == "all"
53
46
  Requires-Dist: sdtfile>=2024.5.24; extra == "all"
54
47
  Requires-Dist: ptufile>=2024.9.14; extra == "all"
55
- Requires-Dist: liffile>=2025.1.30; extra == "all"
48
+ Requires-Dist: liffile>=2025.2.10; extra == "all"
49
+ Requires-Dist: pawflim; extra == "all"
50
+ Dynamic: license-file
56
51
 
57
52
  # PhasorPy
58
53
 
@@ -0,0 +1,26 @@
1
+ phasorpy/__init__.py,sha256=SwOTreV7wd8ZEL3waXQlgbNnsErWJ0dh6A2d77DWp0Y,254
2
+ phasorpy/__main__.py,sha256=0u6C98HYfajV1RoUww8kAc0CxdsON0ijgEyTYExCSLM,149
3
+ phasorpy/_io.py,sha256=iT6yzCCbzW3R5OvN2aDuGgfAhfzTXQDOIyRCNnSxdnA,86658
4
+ phasorpy/_phasorpy.cp312-win_arm64.pyd,sha256=oZhX1QKpo76NBai-ig1bJTWMnGCHNug7v5Tacrop--Y,724992
5
+ phasorpy/_phasorpy.pyx,sha256=0miKMEcc1dsohc252uTFiEWUdthzwx7jNVLDuQKZGPY,64124
6
+ phasorpy/_typing.py,sha256=ii-5-8KTs2BZq0Ytu3yJl8ejSQj1V06c1_Jcwa_2Snk,1324
7
+ phasorpy/_utils.py,sha256=5x3mDxabSBq52aO1hUkeIVsqBsoBfs5FEcCLB0aFZgU,17401
8
+ phasorpy/cli.py,sha256=_p0NYuA3EYgz5OI3Jvpo0G48UO6hhMuo5nHOTMUO74o,2004
9
+ phasorpy/cluster.py,sha256=Ai3jrBKTwL0VJ0T61NL_FPB88Xgo7YVP1c-FLSKmUs0,5001
10
+ phasorpy/color.py,sha256=Y0XINGWDI5DxTUO9FnwYbf3oZq9IB2XagoJOdXhEsvQ,17378
11
+ phasorpy/components.py,sha256=qIZ91o22Dua0Dx189t-UGkO2AEQD296INTAUHYoomtA,10455
12
+ phasorpy/conftest.py,sha256=0dCO8UZtEnhZv-JW1_vGvPZOmaihRLOo_Wc857socWI,976
13
+ phasorpy/cursors.py,sha256=1KzsfZBD-kKLdjiMUC3ZIKjSnVtnUwggVlt883EmcRo,15571
14
+ phasorpy/datasets.py,sha256=EggCWJnpHIHuobRV7aEBNM44B79hMzInNA_lEnMZum8,20870
15
+ phasorpy/io.py,sha256=xvQD8xGYCxp6LRFRTDguMUeXFSUG29knNd3HPWkTyjg,237
16
+ phasorpy/phasor.py,sha256=NeFmuYEvg9YMlL83sLkhKLO6IJepP5uZsc6BRCYRpuQ,119885
17
+ phasorpy/plot.py,sha256=Jkdwjubhm8rKQuraESW0Sn6tHHxGyryjDBj5n85oTyw,77423
18
+ phasorpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ phasorpy/utils.py,sha256=lBvYpS3WNLIjYcZ2kv1X6V5rFT3zNBqGsnJMEGqay1M,11770
20
+ phasorpy/version.py,sha256=pz2RAbZKrk1cd3jzmZ4lQOry9UzcBMxBO_WGjVpK360,2053
21
+ phasorpy-0.5.dist-info/licenses/LICENSE.txt,sha256=KVzeDa0MBRSUYPFFNuo7Atn6v62TiJTgGzHigltEX0o,1104
22
+ phasorpy-0.5.dist-info/METADATA,sha256=ULBHKOkw7nFpSd-M9_xUlHUEHJb3_jaTgdaqN8x6W6o,3322
23
+ phasorpy-0.5.dist-info/WHEEL,sha256=pYhIK3qx8EqEUszpzpfBG9Icpl8gWvSYj-z31CXLr10,101
24
+ phasorpy-0.5.dist-info/entry_points.txt,sha256=VRhsl3qGiIKwtMraKapmduchTMbdReUi1AoVTe9f3ss,47
25
+ phasorpy-0.5.dist-info/top_level.txt,sha256=4Y0uYzya5R2loleAxZ6s2n53_FysUbgFTfFaU0i9rbo,9
26
+ phasorpy-0.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-win_arm64
5
5