Skip to content

Commit 6261f4c

Browse files
committed
Add 'num_bins, 'start', and 'stop' parameters to '_get_bins'
1 parent c6b5d8e commit 6261f4c

File tree

1 file changed

+41
-15
lines changed

1 file changed

+41
-15
lines changed

src/napari_matplotlib/histogram.py

+41-15
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,44 @@
2727
_COLORS = {"r": "tab:red", "g": "tab:green", "b": "tab:blue"}
2828

2929

30-
def _get_bins(data: npt.NDArray[Any]) -> npt.NDArray[Any]:
30+
def _get_bins(
31+
data: npt.NDArray[Any],
32+
num_bins: int = 100,
33+
start: Optional[Union[int, float]] = None,
34+
stop: Optional[Union[int, float]] = None,
35+
) -> npt.NDArray[Any]:
36+
"""Create evenly spaced bins with a given interval.
37+
38+
If `start` or `stop` are `None`, they will be set based on the minimum
39+
and maximum values, respectively, of the data.
40+
41+
Parameters
42+
----------
43+
data : napari.layers.Layer.data
44+
Napari layer data.
45+
num_bins : integer, optional
46+
Number of evenly-spaced bins to create.
47+
start : integer or real, optional
48+
Start bin edge. Defaults to the minimum value of `data`.
49+
stop : integer or real, optional
50+
Stop bin edge. Defaults to the maximum value of `data`.
51+
52+
Returns
53+
-------
54+
bin_edges : numpy.ndarray
55+
Array of evenly spaced bin edges.
56+
"""
57+
start = np.min(data) if start is None else start
58+
stop = np.max(data) if stop is None else stop
59+
3160
if data.dtype.kind in {"i", "u"}:
3261
# Make sure integer data types have integer sized bins
33-
step = np.ceil(np.ptp(data) / 100)
34-
return np.arange(np.min(data), np.max(data) + step, step)
62+
step = np.ceil((stop - start) / num_bins)
63+
return np.arange(start, stop + step, step)
3564
else:
36-
# For other data types, just have 100 evenly spaced bins
37-
# (and 101 bin edges)
38-
return np.linspace(np.min(data), np.max(data), 101)
65+
# For other data types we can use exactly `num_bins` bins
66+
# (and `num_bins` + 1 bin edges)
67+
return np.linspace(start, stop, num_bins + 1)
3968

4069

4170
class HistogramWidget(SingleAxesWidget):
@@ -217,15 +246,12 @@ def draw(self) -> None:
217246

218247
# Important to calculate bins after slicing 3D data, to avoid reading
219248
# whole cube into memory.
220-
if data.dtype.kind in {"i", "u"}:
221-
# Make sure integer data types have integer sized bins
222-
step = abs(self.bins_stop - self.bins_start) // (self.bins_num)
223-
step = max(1, step)
224-
bins = np.arange(self.bins_start, self.bins_stop + step, step)
225-
else:
226-
bins = np.linspace(
227-
self.bins_start, self.bins_stop, self.bins_num + 1
228-
)
249+
bins = _get_bins(
250+
data,
251+
num_bins=self.bins_num,
252+
start=self.bins_start,
253+
stop=self.bins_stop,
254+
)
229255

230256
if layer.rgb:
231257
# Histogram RGB channels independently

0 commit comments

Comments
 (0)