Skip to content

Commit 6766b87

Browse files
Merge pull request #169 from haesleinhuepf/handle_negative_labels
visualize negative arrays differently
2 parents 1165dec + e4dc713 commit 6766b87

File tree

6 files changed

+165
-152
lines changed

6 files changed

+165
-152
lines changed

docs/demo.ipynb

Lines changed: 128 additions & 108 deletions
Large diffs are not rendered by default.

docs/label_display.ipynb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
"</table>"
4343
],
4444
"text/plain": [
45-
"StackViewNDArray([[0, 1],\n",
46-
" [2, 3]])"
45+
"[[0 1]\n",
46+
" [2 3]]"
4747
]
4848
},
4949
"execution_count": 2,
@@ -87,8 +87,8 @@
8787
"</table>"
8888
],
8989
"text/plain": [
90-
"StackViewNDArray([[4, 1],\n",
91-
" [2, 3]])"
90+
"[[4 1]\n",
91+
" [2 3]]"
9292
]
9393
},
9494
"execution_count": 3,
@@ -132,8 +132,8 @@
132132
"</table>"
133133
],
134134
"text/plain": [
135-
"StackViewNDArray([[5, 1],\n",
136-
" [2, 3]])"
135+
"[[5 1]\n",
136+
" [2 3]]"
137137
]
138138
},
139139
"execution_count": 4,
@@ -159,7 +159,7 @@
159159
"<table>\n",
160160
"<tr>\n",
161161
"<td>\n",
162-
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAACQpJREFUeJzt2LFtAlEUBVFApC7CmbcUROKQUijBgfsjdeQ2PlUsT2jOqeCGo3tca60DAAAZp+kBAAC8lgAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQMx5egDv6/G1TU+AXV2+f6cnwK7+fq7TExjiAQQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiztMDeF/b7X96Auzq4/M+PQF2dp0ewBAPIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYo5rrTU9AgCA1/EAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGKexQgSE/40h/EAAAAASUVORK5CYII=\"></img>\n",
162+
"<img src=\"data:image/png;base64,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IEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBijpmZ7REAANyPBxAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQ8w90ghq0C8ySUgAAAABJRU5ErkJggg==\"></img>\n",
163163
"</td>\n",
164164
"<td style=\"text-align: center; vertical-align: top;\">\n",
165165
"\n",
@@ -175,8 +175,8 @@
175175
"</table>"
176176
],
177177
"text/plain": [
178-
"StackViewNDArray([[ 4, 1],\n",
179-
" [ 2, -3]])"
178+
"[[ 4 1]\n",
179+
" [ 2 -3]]"
180180
]
181181
},
182182
"execution_count": 5,

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="stackview",
8-
version="0.16.2",
8+
version="0.17.0",
99
author="Robert Haase",
1010
author_email="[email protected]",
1111
description="Interactive image stack viewing in jupyter notebooks",

stackview/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.16.2"
1+
__version__ = "0.17.0"
22

33
from ._static_view import jupyter_displayable_output, insight
44
from ._utilities import merge_rgb

stackview/_imshow.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,9 @@ def imshow(image,
9191
colormap = imshow.labels_cmap
9292

9393
if min_display_intensity is None:
94-
min_display_intensity = 0
94+
min_display_intensity = min(0, image.min())
9595
if max_display_intensity is None:
96-
max_display_intensity = 65536
97-
98-
if image.min() < 0:
99-
image = np.abs(image)
96+
max_display_intensity = min_display_intensity + 65536
10097

10198
if plot is None:
10299
import matplotlib.pyplot as plt

stackview/_static_view.py

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,26 @@ class StackViewNDArray(np.ndarray):
3737
def __new__(cls, input_array, library_name=None, help_url=None):
3838
if 'cupy.ndarray' in str(type(input_array)):
3939
input_array = input_array.get()
40-
obj = np.asarray(input_array).view(cls)
40+
input_array = np.asarray(input_array)
41+
obj = super(StackViewNDArray, cls).__new__(cls, shape=input_array.shape, dtype=input_array.dtype)
4142
obj.library_name = library_name
4243
obj.help_url = help_url
44+
obj[:] = input_array
4345
return obj
4446

4547
def __array_finalize__(self, obj):
4648
if obj is None: return
4749
self.library_name = getattr(obj, 'library_name', None)
4850
self.help_url = getattr(obj, 'help_url', None)
49-
self.obj = obj
50-
51-
def __getattr__(self, name):
52-
if name == "__repr__":
53-
return self.__repr__
54-
if name == "_repr_html_":
55-
return self._repr_html_
56-
return getattr(self.obj, name)
57-
51+
#self.obj = obj
5852

5953
def __repr__(self):
6054
if _is_running_in_colab():
6155
from IPython.display import display, HTML
6256
display(HTML(self._repr_html_()))
6357
return ""
6458
else:
65-
return self.obj.__repr__()
59+
return str(self)
6660

6761

6862
def _repr_html_(self):
@@ -71,19 +65,19 @@ def _repr_html_(self):
7165
-------
7266
HTML text with the image and some properties.
7367
"""
74-
if len(self.obj.shape) < 2:
75-
return str(self.obj)
68+
if len(self.shape) < 2:
69+
return str(self)
7670

7771
import numpy as np
78-
size_in_pixels = np.prod(self.obj.shape)
79-
size_in_bytes = size_in_pixels * self.obj.dtype.itemsize
72+
size_in_pixels = np.prod(self.shape)
73+
size_in_bytes = size_in_pixels * self.dtype.itemsize
8074

8175
from ._image_widget import _is_label_image
82-
labels = _is_label_image(self.obj)
76+
labels = _is_label_image(self)
8377

8478
import matplotlib.pyplot as plt
8579
from ._imshow import imshow
86-
imshow(self.obj,
80+
imshow(self,
8781
labels=labels,
8882
continue_drawing=True,
8983
colorbar=not labels)
@@ -110,7 +104,7 @@ def _repr_html_(self):
110104
import numpy as np
111105

112106
num_bins = 32
113-
h, _ = np.histogram(self.obj, bins=num_bins)
107+
h, _ = np.histogram(self, bins=num_bins)
114108

115109
plt.figure(figsize=(1.8, 1.2))
116110
plt.bar(range(0, len(h)), h)
@@ -125,22 +119,24 @@ def _repr_html_(self):
125119

126120
histogram = _png_to_html(_plt_to_png())
127121

128-
min_intensity = self.obj.min()
129-
max_intensity = self.obj.max()
122+
min_intensity = self.min()
123+
max_intensity = self.max()
130124
min_max = "<tr><td>min</td><td>" + str(min_intensity) + "</td></tr>" + \
131125
"<tr><td>max</td><td>" + str(max_intensity) + "</td></tr>"
132126

133127
if labels:
134-
unique_labels = list(np.unique(self.obj))
128+
unique_labels = list(np.unique(self))
135129
if 0 in unique_labels:
136130
unique_labels.remove(0)
137131

138132
num_labels = len(unique_labels)
139133
min_max += "<tr><td>n labels</td><td>" + str(num_labels) + "</td></tr>"
140-
if max_intensity != num_labels:
141-
min_max += "<tr><td colspan=\"2\"><a href=\"https://haesleinhuepf.github.io/BioImageAnalysisNotebooks/20h_segmentation_post_processing/sequential_labeling.html\" style=\"color:darkred; font-weight:bold\">Not sequentially labeled!</a></td></tr>"
142134
if min_intensity < 0:
143135
min_max += "<tr><td colspan=\"2\" style=\"color:darkred; font-weight:bold\">Negative label values detected!</td></tr>"
136+
else:
137+
if max_intensity != num_labels:
138+
min_max += "<tr><td colspan=\"2\"><a href=\"https://haesleinhuepf.github.io/BioImageAnalysisNotebooks/20h_segmentation_post_processing/sequential_labeling.html\" style=\"color:darkred; font-weight:bold\">Not sequentially labeled!</a></td></tr>"
139+
144140
else:
145141
min_max = ""
146142

@@ -236,8 +232,8 @@ def _imshow(image, title: str = None, labels: bool = False, min_display_intensit
236232
continue_drawing: float
237233
True: the next shown image can be visualized on top of the current one, e.g. with alpha = 0.5
238234
"""
235+
return
239236
import numpy as np
240-
241237
if len(image.shape) == 3 and image.shape[2] == 3: # RGB image
242238
import matplotlib.pyplot as plt
243239
plt.imshow(image, vmin=min_display_intensity, vmax=max_display_intensity,
@@ -261,10 +257,10 @@ def _imshow(image, title: str = None, labels: bool = False, min_display_intensit
261257
import matplotlib
262258
import numpy as np
263259

264-
if not hasattr(_imshow, "labels_cmap"):
260+
if not hasattr(imshow, "labels_cmap"):
265261
from ._image_widget import _labels_lut
266-
_imshow.labels_cmap = matplotlib.colors.ListedColormap(_labels_lut())
267-
cmap = _imshow.labels_cmap
262+
imshow.labels_cmap = matplotlib.colors.ListedColormap(_labels_lut())
263+
cmap = imshow.labels_cmap
268264

269265
if min_display_intensity is None:
270266
min_display_intensity = 0
@@ -284,4 +280,4 @@ def _imshow(image, title: str = None, labels: bool = False, min_display_intensit
284280
plot.imshow(image, cmap=cmap, vmin=min_display_intensity, vmax=max_display_intensity,
285281
interpolation='nearest', alpha=alpha)
286282
if colorbar:
287-
plot.colorbar()
283+
plot.colorbar()

0 commit comments

Comments
 (0)