Skip to content

Commit a5e7be1

Browse files
authored
Merge pull request #4593 from ales-erjavec/distancemap-legend
[ENH] Distance Map: Add a color map legend
2 parents 5c52251 + 6e5c50b commit a5e7be1

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

Orange/widgets/unsupervised/owdistancemap.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
from Orange.widgets.utils.widgetpreview import WidgetPreview
2828
from Orange.widgets.widget import Input, Output
2929
from Orange.widgets.utils.dendrogram import DendrogramWidget
30+
from Orange.widgets.visualize.utils.heatmap import (
31+
GradientColorMap, GradientLegendWidget,
32+
)
3033

3134

3235
def _remove_item(item):
@@ -74,8 +77,6 @@ def __select(self, area, command):
7477

7578
if command & self.Select:
7679
area = area.normalized()
77-
intersects = [rect.intersects(area)
78-
for item, rect in self.__selections]
7980

8081
def partition(predicate, iterable):
8182
t1, t2 = itertools.tee(iterable)
@@ -287,6 +288,7 @@ def __init__(self):
287288
super().__init__()
288289

289290
self.matrix = None
291+
self._matrix_range = 0.
290292
self._tree = None
291293
self._ordered_tree = None
292294
self._sorted_matrix = None
@@ -308,12 +310,6 @@ def __init__(self):
308310
labelAlignment=Qt.AlignLeft,
309311
fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow
310312
)
311-
# form.addRow(
312-
# "Gamma",
313-
# gui.hSlider(box, self, "color_gamma", minValue=0.0, maxValue=1.0,
314-
# step=0.05, ticks=True, intOnly=False,
315-
# createLabel=False, callback=self._update_color)
316-
# )
317313
form.addRow(
318314
"Low:",
319315
gui.hSlider(box, self, "color_low", minValue=0.0, maxValue=1.0,
@@ -344,10 +340,16 @@ def __init__(self):
344340
self.grid = QGraphicsGridLayout()
345341
self.grid_widget.setLayout(self.grid)
346342

343+
self.gradient_legend = GradientLegendWidget(
344+
0, 1, self._color_map()
345+
)
346+
self.gradient_legend.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
347+
self.gradient_legend.setMaximumWidth(250)
348+
self.grid.addItem(self.gradient_legend, 0, 1)
347349
self.viewbox = pg.ViewBox(enableMouse=False, enableMenu=False)
348350
self.viewbox.setAcceptedMouseButtons(Qt.NoButton)
349351
self.viewbox.setAcceptHoverEvents(False)
350-
self.grid.addItem(self.viewbox, 1, 1)
352+
self.grid.addItem(self.viewbox, 2, 1)
351353

352354
self.left_dendrogram = DendrogramWidget(
353355
self.grid_widget, orientation=DendrogramWidget.Left,
@@ -365,8 +367,8 @@ def __init__(self):
365367
self.top_dendrogram.setAcceptedMouseButtons(Qt.NoButton)
366368
self.top_dendrogram.setAcceptHoverEvents(False)
367369

368-
self.grid.addItem(self.left_dendrogram, 1, 0)
369-
self.grid.addItem(self.top_dendrogram, 0, 1)
370+
self.grid.addItem(self.left_dendrogram, 2, 0)
371+
self.grid.addItem(self.top_dendrogram, 1, 1)
370372

371373
self.right_labels = TextList(
372374
alignment=Qt.AlignLeft | Qt.AlignVCenter,
@@ -378,11 +380,12 @@ def __init__(self):
378380
sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
379381
)
380382

381-
self.grid.addItem(self.right_labels, 1, 2)
382-
self.grid.addItem(self.bottom_labels, 2, 1)
383+
self.grid.addItem(self.right_labels, 2, 2)
384+
self.grid.addItem(self.bottom_labels, 3, 1)
383385

384386
self.view.setCentralItem(self.grid_widget)
385387

388+
self.gradient_legend.hide()
386389
self.left_dendrogram.hide()
387390
self.top_dendrogram.hide()
388391
self.right_labels.hide()
@@ -391,8 +394,6 @@ def __init__(self):
391394
self.matrix_item = None
392395
self.dendrogram = None
393396

394-
self.grid_widget.scene().installEventFilter(self)
395-
396397
self.settingsAboutToBePacked.connect(self.pack_settings)
397398

398399
def pack_settings(self):
@@ -414,8 +415,10 @@ def set_distances(self, matrix):
414415

415416
self.matrix = matrix
416417
if matrix is not None:
418+
self._matrix_range = numpy.nanmax(matrix)
417419
self.set_items(matrix.row_items, matrix.axis)
418420
else:
421+
self._matrix_range = 0.
419422
self.set_items(None)
420423

421424
if matrix is not None:
@@ -469,7 +472,6 @@ def set_items(self, items, axis=1):
469472

470473
def clear(self):
471474
self.matrix = None
472-
self.cluster = None
473475
self._tree = None
474476
self._ordered_tree = None
475477
self._sorted_matrix = None
@@ -499,6 +501,7 @@ def remove(item):
499501

500502
self._set_displayed_dendrogram(None)
501503
self._set_labels(None)
504+
self.gradient_legend.hide()
502505

503506
def _cluster_tree(self):
504507
if self._tree is None:
@@ -607,12 +610,22 @@ def _set_labels(self, labels):
607610
self.right_labels.setMaximumWidth(constraint)
608611
self.bottom_labels.setMaximumHeight(constraint)
609612

613+
def _color_map(self) -> GradientColorMap:
614+
palette = self.color_box.currentData()
615+
return GradientColorMap(
616+
palette.lookup_table(),
617+
thresholds=(self.color_low, max(self.color_high, self.color_low)),
618+
span=(0., self._matrix_range))
619+
610620
def _update_color(self):
611621
palette = self.color_box.currentData()
612622
self.palette_name = palette.name
613623
if self.matrix_item:
614624
colors = palette.lookup_table(self.color_low, self.color_high)
615625
self.matrix_item.setLookupTable(colors)
626+
self.gradient_legend.show()
627+
self.gradient_legend.setRange(0, self._matrix_range)
628+
self.gradient_legend.setColorMap(self._color_map())
616629

617630
def _invalidate_selection(self):
618631
ranges = self.matrix_item.selections()

Orange/widgets/visualize/utils/heatmap.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class GradientColorMap(ColorMap):
8686
def __init__(self, colortable, thresholds=thresholds, center=None, span=None):
8787
self.colortable = np.asarray(colortable)
8888
self.thresholds = thresholds
89-
assert thresholds[0] < thresholds[1]
89+
assert thresholds[0] <= thresholds[1]
9090
self.center = center
9191
self.span = span
9292

@@ -1159,6 +1159,12 @@ def __init__(
11591159
if parent is not None:
11601160
self.setParentItem(parent)
11611161

1162+
def setRange(self, low, high):
1163+
if self.low != low or self.high != high:
1164+
self.low = low
1165+
self.high = high
1166+
self.__update()
1167+
11621168
def setColorMap(self, colormap: ColorMap) -> None:
11631169
"""Set the color map"""
11641170
self.colormap = colormap
@@ -1180,6 +1186,7 @@ def __update(self):
11801186
tick_values = [low, high]
11811187
tickformat = "{:.6g}".format
11821188
ticks = [(val, tickformat(val)) for val in tick_values]
1189+
self.__axis.setRange(low, high)
11831190
self.__axis.setTicks([ticks])
11841191

11851192
self.updateGeometry()

0 commit comments

Comments
 (0)