Skip to content

Commit

Permalink
Merge pull request #744 from markotoplak/image-adapt
Browse files Browse the repository at this point in the history
Refactor ImagePlot to be more adaptable
  • Loading branch information
markotoplak authored Sep 24, 2024
2 parents 2997066 + f7c0090 commit 5228ede
Showing 1 changed file with 89 additions and 63 deletions.
152 changes: 89 additions & 63 deletions orangecontrib/spectroscopy/widgets/owhyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,31 @@ def color_palette_model(palettes, iconsize=QSize(64, 16)):
return model


class AxesSettingsMixin:

def __init__(self):
self.xy_model = DomainModel(DomainModel.METAS | DomainModel.CLASSES,
valid_types=DomainModel.PRIMITIVE)

def setup_axes_settings_box(self):
box = gui.vBox(self)

common_options = {
"labelWidth": 50,
"orientation": Qt.Horizontal,
"sendSelectedValue": True
}

cb_attr_x = gui.comboBox(
box, self, "attr_x", label="Axis x:", callback=self.update_attr,
model=self.xy_model, **common_options)
gui.comboBox(
box, self, "attr_y", label="Axis y:", callback=self.update_attr,
model=self.xy_model, **common_options)
box.setFocusProxy(cb_attr_x)
return box


class ImageColorSettingMixin:
threshold_low = Setting(0.0, schema_only=True)
threshold_high = Setting(1.0, schema_only=True)
Expand Down Expand Up @@ -529,6 +554,53 @@ def add_zoom_actions(self, menu):
menu.addAction(zoom_fit)


class ImageSelectionMixin:

def add_selection_actions(self, menu):

select_square = QAction(
"Select (square)", self, triggered=self.plot.vb.set_mode_select_square,
)
select_square.setShortcuts([Qt.Key_S])
select_square.setShortcutContext(Qt.WidgetWithChildrenShortcut)
self.addAction(select_square)
if menu:
menu.addAction(select_square)

select_polygon = QAction(
"Select (polygon)", self, triggered=self.plot.vb.set_mode_select_polygon,
)
select_polygon.setShortcuts([Qt.Key_P])
select_polygon.setShortcutContext(Qt.WidgetWithChildrenShortcut)
self.addAction(select_polygon)
if menu:
menu.addAction(select_polygon)

def select_square(self, p1, p2):
""" Select elements within a square drawn by the user.
A selection needs to contain whole pixels """
x1, y1 = p1.x(), p1.y()
x2, y2 = p2.x(), p2.y()
polygon = [QPointF(x1, y1), QPointF(x2, y1), QPointF(x2, y2), QPointF(x1, y2), QPointF(x1, y1)]
self.select_polygon(polygon)

def select_polygon(self, polygon):
""" Select by a polygon which has to contain whole pixels. """
if self.data and self.lsx and self.lsy:
polygon = [(p.x(), p.y()) for p in polygon]
# a polygon should contain all pixel
shiftx = _shift(self.lsx)
shifty = _shift(self.lsy)
points_edges = [self.data_points + [[shiftx, shifty]],
self.data_points + [[-shiftx, shifty]],
self.data_points + [[shiftx, -shifty]],
self.data_points + [[-shiftx, -shifty]]]
inp = in_polygon(points_edges[0], polygon)
for p in points_edges[1:]:
inp *= in_polygon(p, polygon)
self.make_selection(inp)


class ImageColorLegend(GraphicsWidget):

def __init__(self):
Expand Down Expand Up @@ -622,12 +694,11 @@ def legend_items(self):
return []


class ImagePlot(QWidget, OWComponent, SelectionGroupMixin,
ImageColorSettingMixin, ImageRGBSettingMixin,
ImageZoomMixin, ConcurrentMixin):
class BasicImagePlot(QWidget, OWComponent, SelectionGroupMixin,
AxesSettingsMixin, ImageSelectionMixin,
ImageColorSettingMixin, ImageRGBSettingMixin,
ImageZoomMixin, ConcurrentMixin):

attr_x = ContextSetting(None, exclude_attributes=True)
attr_y = ContextSetting(None, exclude_attributes=True)
gamma = Setting(0)

selection_changed = Signal()
Expand All @@ -637,6 +708,8 @@ def __init__(self, parent):
QWidget.__init__(self)
OWComponent.__init__(self, parent)
SelectionGroupMixin.__init__(self)
AxesSettingsMixin.__init__(self)
ImageSelectionMixin.__init__(self)
ImageColorSettingMixin.__init__(self)
ImageZoomMixin.__init__(self)
ConcurrentMixin.__init__(self)
Expand Down Expand Up @@ -694,56 +767,28 @@ def __init__(self, parent):
# prepare interface according to the new context
self.parent.contextAboutToBeOpened.connect(lambda x: self.init_interface_data(x[0]))

actions = []

self.add_zoom_actions(view_menu)

select_square = QAction(
"Select (square)", self, triggered=self.plot.vb.set_mode_select_square,
)
select_square.setShortcuts([Qt.Key_S])
select_square.setShortcutContext(Qt.WidgetWithChildrenShortcut)
actions.append(select_square)

select_polygon = QAction(
"Select (polygon)", self, triggered=self.plot.vb.set_mode_select_polygon,
)
select_polygon.setShortcuts([Qt.Key_P])
select_polygon.setShortcutContext(Qt.WidgetWithChildrenShortcut)
actions.append(select_polygon)
self.add_selection_actions(view_menu)

if self.saving_enabled:
save_graph = QAction(
"Save graph", self, triggered=self.save_graph,
)
save_graph.setShortcuts([QKeySequence(Qt.ControlModifier | Qt.Key_I)])
actions.append(save_graph)

view_menu.addActions(actions)
self.addActions(actions)
for a in actions:
a.setShortcutVisibleInContextMenu(True)

common_options = dict(
labelWidth=50, orientation=Qt.Horizontal, sendSelectedValue=True)
self.addAction(save_graph)
view_menu.addAction(save_graph)
save_graph.setShortcutVisibleInContextMenu(True)

choose_xy = QWidgetAction(self)
box = gui.vBox(self)
box.setContentsMargins(10, 0, 10, 0)
box.setFocusPolicy(Qt.TabFocus)
self.xy_model = DomainModel(DomainModel.METAS | DomainModel.CLASSES,
valid_types=DomainModel.PRIMITIVE)
self.cb_attr_x = gui.comboBox(
box, self, "attr_x", label="Axis x:", callback=self.update_attr,
model=self.xy_model, **common_options)
self.cb_attr_y = gui.comboBox(
box, self, "attr_y", label="Axis y:", callback=self.update_attr,
model=self.xy_model, **common_options)
box.setFocusProxy(self.cb_attr_x)

self.axes_settings_box = self.setup_axes_settings_box()
self.color_settings_box = self.setup_color_settings_box()
self.rgb_settings_box = self.setup_rgb_settings_box()

box.layout().addWidget(self.axes_settings_box)
box.layout().addWidget(self.color_settings_box)
box.layout().addWidget(self.rgb_settings_box)

Expand Down Expand Up @@ -830,30 +875,6 @@ def make_selection(self, selected):
self.prepare_settings_for_saving()
self.selection_changed.emit()

def select_square(self, p1, p2):
""" Select elements within a square drawn by the user.
A selection needs to contain whole pixels """
x1, y1 = p1.x(), p1.y()
x2, y2 = p2.x(), p2.y()
polygon = [QPointF(x1, y1), QPointF(x2, y1), QPointF(x2, y2), QPointF(x1, y2), QPointF(x1, y1)]
self.select_polygon(polygon)

def select_polygon(self, polygon):
""" Select by a polygon which has to contain whole pixels. """
if self.data and self.lsx and self.lsy:
polygon = [(p.x(), p.y()) for p in polygon]
# a polygon should contain all pixel
shiftx = _shift(self.lsx)
shifty = _shift(self.lsy)
points_edges = [self.data_points + [[shiftx, shifty]],
self.data_points + [[-shiftx, shifty]],
self.data_points + [[shiftx, -shifty]],
self.data_points + [[-shiftx, -shifty]]]
inp = in_polygon(points_edges[0], polygon)
for p in points_edges[1:]:
inp *= in_polygon(p, polygon)
self.make_selection(inp)

def _points_at_pos(self, pos):
if self.data and self.lsx and self.lsy:
x, y = pos.x(), pos.y()
Expand Down Expand Up @@ -1020,6 +1041,11 @@ def on_exception(self, ex: Exception):
raise ex


class ImagePlot(BasicImagePlot):
attr_x = ContextSetting(None, exclude_attributes=True)
attr_y = ContextSetting(None, exclude_attributes=True)


class CurvePlotHyper(CurvePlot):
viewtype = Setting(AVERAGE) # average view by default

Expand Down

0 comments on commit 5228ede

Please sign in to comment.