From 7b60baa7cc9789b198cc31428cadd764bfa9a423 Mon Sep 17 00:00:00 2001 From: Jernej Urankar Date: Wed, 2 Aug 2017 14:39:28 +0200 Subject: [PATCH 1/6] Plotutils: common tools for various widgets --- Orange/widgets/visualize/utils/plotutils.py | 100 ++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 Orange/widgets/visualize/utils/plotutils.py diff --git a/Orange/widgets/visualize/utils/plotutils.py b/Orange/widgets/visualize/utils/plotutils.py new file mode 100644 index 00000000000..9d81b6bded6 --- /dev/null +++ b/Orange/widgets/visualize/utils/plotutils.py @@ -0,0 +1,100 @@ +import numpy as np + +from AnyQt.QtWidgets import QGraphicsLineItem +from AnyQt.QtCore import QRectF, QLineF +from AnyQt.QtGui import QTransform + +import pyqtgraph as pg + + +class TextItem(pg.TextItem): + if not hasattr(pg.TextItem, "setAnchor"): + # Compatibility with pyqtgraph <= 0.9.10; in (as of yet unreleased) + # 0.9.11 the TextItem has a `setAnchor`, but not `updateText` + def setAnchor(self, anchor): + self.anchor = pg.Point(anchor) + self.updateText() + + +class AnchorItem(pg.GraphicsObject): + def __init__(self, parent=None, line=QLineF(), text="", **kwargs): + super().__init__(parent, **kwargs) + self._text = text + self.setFlag(pg.GraphicsObject.ItemHasNoContents) + + self._spine = QGraphicsLineItem(line, self) + angle = line.angle() + + self._arrow = pg.ArrowItem(parent=self, angle=0) + self._arrow.setPos(self._spine.line().p2()) + self._arrow.setRotation(angle) + self._arrow.setStyle(headLen=10) + + self._label = TextItem(text=text, color=(10, 10, 10)) + self._label.setParentItem(self) + self._label.setPos(self._spine.line().p2()) + + if parent is not None: + self.setParentItem(parent) + + def setText(self, text): + if text != self._text: + self._text = text + self._label.setText(text) + self._label.setVisible(bool(text)) + + def text(self): + return self._text + + def setLine(self, *line): + line = QLineF(*line) + if line != self._spine.line(): + self._spine.setLine(line) + self.__updateLayout() + + def line(self): + return self._spine.line() + + def setPen(self, pen): + self._spine.setPen(pen) + + def setArrowVisible(self, visible): + self._arrow.setVisible(visible) + + def paint(self, painter, option, widget): + pass + + def boundingRect(self): + return QRectF() + + def viewTransformChanged(self): + self.__updateLayout() + + def __updateLayout(self): + T = self.sceneTransform() + if T is None: + T = QTransform() + + # map the axis spine to scene coord. system. + viewbox_line = T.map(self._spine.line()) + angle = viewbox_line.angle() + assert not np.isnan(angle) + # note in Qt the y axis is inverted (90 degree angle 'points' down) + left_quad = 270 < angle <= 360 or -0.0 <= angle < 90 + + # position the text label along the viewbox_line + label_pos = self._spine.line().pointAt(0.90) + + if left_quad: + # Anchor the text under the axis spine + anchor = (0.5, -0.1) + else: + # Anchor the text over the axis spine + anchor = (0.5, 1.1) + + self._label.setPos(label_pos) + self._label.setAnchor(pg.Point(*anchor)) + self._label.setRotation(-angle if left_quad else 180 - angle) + + self._arrow.setPos(self._spine.line().p2()) + self._arrow.setRotation(180 - angle) From f361fce08986a1e68656ea438ccd0463deca1467 Mon Sep 17 00:00:00 2001 From: Jernej Urankar Date: Tue, 10 Oct 2017 10:14:39 +0200 Subject: [PATCH 2/6] Freeviz: widget icon --- Orange/widgets/visualize/icons/Freeviz.svg | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Orange/widgets/visualize/icons/Freeviz.svg diff --git a/Orange/widgets/visualize/icons/Freeviz.svg b/Orange/widgets/visualize/icons/Freeviz.svg new file mode 100644 index 00000000000..f03732db31c --- /dev/null +++ b/Orange/widgets/visualize/icons/Freeviz.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7240c4d469767797d86c4ef86e3fd47dffe48130 Mon Sep 17 00:00:00 2001 From: Jernej Urankar Date: Tue, 10 Oct 2017 13:21:27 +0200 Subject: [PATCH 3/6] FreeViz: freeviz documentation icon --- .../source/widgets/visualize/icons/freeviz.png | Bin 0 -> 1543 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/visual-programming/source/widgets/visualize/icons/freeviz.png diff --git a/doc/visual-programming/source/widgets/visualize/icons/freeviz.png b/doc/visual-programming/source/widgets/visualize/icons/freeviz.png new file mode 100644 index 0000000000000000000000000000000000000000..145dcec87d0f64876ce83a9dd9233143bdec64df GIT binary patch literal 1543 zcmV+i2Kf1jP)SbA8WGJ4_J}ObfrlIvEV+G(wW-++1yeY zs8E?OMNm+-rs)u8*ccuC$h~dnKw91K-((*QyE>&4-Bgf;t+kEG%{}{bD@l5r+`6O@ z)&qgO?>+a;`{aGjbIy5zMO(E0w^6Yc?(grf5k;|&nH8VUx2IUYBmLI}n3+PMP#Y1o z0B{26U9x0JP!NPFW_AH6E9MDEkFvR@rlyG*pU%$C79u*D_F5p3NH~e;7BhpHM@t4^ zuFU~>BW-TiEM5|A*LD3o5rK%V6cd1u=egn=3Cb z=d@wOWb-`$RuEA#kw{!CC4h*@Tz6w*V|-@N+}zwjMEd~z4&WXUbyieVoB|*+^R^ z)S54_iKvR10idY-w?d&u3T$21tBm=_547atQrpb)$;ruQ0N4PGZ{EE5em)Ti1OjaU9twh{X~EN{Pfu9& znKuBlz|OK6{^zC7?%lgv0AvV)BuN>9kk3ab^pP@imGSl0432eo+oRFwmVAN$VEf*^ zd+kk%SaoArM8nKNhNX_B1Nr=Ta$-rg<%SZ(}sV@5_EzH#G* zYjkuJ@pxQf=5m9_p{}m34ge3!5CEOYWU?iF&3rxu?a2E2`c{gfI1b>hA-6#Q7#<$J zJ2f@6Jj*@la5$bkapJ^uNjtKP#UyEsQ9>*?Hm?DAZ+d$Abz^Q$u3MDUf+VtB0sMU0 z@E$Y2;`8}V>AG%Ka%XToO)gggST;kmVr1f3cJAD{3RP840XS?-B}7r&;P?B#wZh|h zNNQmz)ZN`J+HAH!B9ZtIz*2)UF#zSMRO$dT?=lh}hr{7q$q#}c=m!0A(X4PMpeRbM zEX$XP=o0`-iD-nG-MX&V64BoP-cnVy-ExI!fo27{7gAOADQ5l%z?%SwnQsY#u;1(T zo=rgLQRv zjQ|c9KQP72$I8mej%?hxF>Z1~O#nV6q9hS{>+9>kS+JJU?RK{U_&B3NtE!r8XlQU6 z!-110PyP~%#dgd9wApOIOP4N9WPvygU_XEfX0G-7{XZ;JKQK!X#>U2+$z<{;K@eU( zbm-96u~_T_04o42W9C3S9-k$7Ua$8cGoJ{o+ Date: Fri, 25 Aug 2017 11:21:01 +0200 Subject: [PATCH 4/6] FreeViz: documentation --- doc/visual-programming/source/index.rst | 1 + .../source/widgets/visualize/freeviz.rst | 121 ++++++++++++++++++ .../images/FreeViz-Example-Explorative.png | Bin 0 -> 81008 bytes .../visualize/images/FreeViz-selection.png | Bin 0 -> 25199 bytes .../visualize/images/freeviz-moveanchor.png | Bin 0 -> 8754 bytes .../visualize/images/freeviz-zoo-stamped.png | Bin 0 -> 27838 bytes 6 files changed, 122 insertions(+) create mode 100644 doc/visual-programming/source/widgets/visualize/freeviz.rst create mode 100644 doc/visual-programming/source/widgets/visualize/images/FreeViz-Example-Explorative.png create mode 100644 doc/visual-programming/source/widgets/visualize/images/FreeViz-selection.png create mode 100644 doc/visual-programming/source/widgets/visualize/images/freeviz-moveanchor.png create mode 100644 doc/visual-programming/source/widgets/visualize/images/freeviz-zoo-stamped.png diff --git a/doc/visual-programming/source/index.rst b/doc/visual-programming/source/index.rst index 8f667d11098..90e45836b2e 100644 --- a/doc/visual-programming/source/index.rst +++ b/doc/visual-programming/source/index.rst @@ -73,6 +73,7 @@ Visualize widgets/visualize/treeviewer widgets/visualize/geomap widgets/visualize/nomogram + widgets/visualize/freeviz Model diff --git a/doc/visual-programming/source/widgets/visualize/freeviz.rst b/doc/visual-programming/source/widgets/visualize/freeviz.rst new file mode 100644 index 00000000000..96e0b97a365 --- /dev/null +++ b/doc/visual-programming/source/widgets/visualize/freeviz.rst @@ -0,0 +1,121 @@ +======= +FreeViz +======= + +.. figure:: icons/freeviz.png + +Displays FreeViz projection. + +Signals +------- + +**Inputs**: + +- **Data** + + An input data set. + +- **Data Subset** + + A subset of instances from the input data set. + +**Outputs**: + +- **Selected Data** + + A subset of instances that the user manually selected from the + freeviz plot. + +- **Data** + + Data with an additional column showing whether a point is selected. If more + than one group is selected then also the group name is written instead. + +- **Components** + + FreeViz vectors + + + +Description +----------- + +**FreeViz** uses a paradigm borrowed from particle physics: points in the same class attract +each other, those from different class repel each other, and the resulting forces are exerted on +the anchors of the attributes, that is, on unit vectors of each of the dimensional axis. The points +cannot move (are projected in the projection space), but the attribute anchors can, so the +optimization process is a hill-climbing optimization where at the end the anchors are placed such +that forces are in equilibrium. The button Optimize is used to invoke the optimization process. +The result of the optimization may depend on the initial placement of the anchors, which can be set +in a circle, arbitrary or even manually. The later also works at any stage of optimization, and we +recommend to play with this option in order to understand how a change of one anchor affects the +positions of the data points. In any linear projection, projections of unit vector that are very +short compared to the others indicate that their associated attribute is not very informative for +particular classification task. Those vectors, that is, their corresponding anchors, may be hidden +from the visualization using Radius slider in Show anchors box. + +.. figure:: images/freeviz-zoo-stamped.png + +1. Two initial positions of anchors are possible: random and circular. Optimization + moves anchors in an optimal position. +2. Set the color of the displayed points (you will get colors for discrete + values and grey-scale points for continuous). Set label, shape and + size to differentiate between points. Set symbol size and opacity for + all data points. +3. Anchors inside a circle are hidden. Circle radius can be be changed using a slider. +4. Adjust *plot properties*: + + - Set `jittering `_ to prevent + the dots from overlapping (especially for discrete attributes). + + - *Show legend* displays a legend on the right. Click and drag the legend to move it. + + - *Show class density* colors the graph by class (see the screenshot below). + + - *Label only selected points* allows you to select individual data instances and label them. + +5. *Select, zoom, pan and zoom to fit* are the options for exploring the graph. + The manual selection of data instances works as an angular/square + selection tool. Double click to move the projection. Scroll in or out + for zoom. +6. If *Send automatically* is ticked, changes are communicated automatically. + Alternatively, press *Send*. +7. *Save Image* saves the created image to your computer in a .svg or .png + format. +8. Produce a report. + +Manually move anchors +--------------------- + +.. figure:: images/freeviz-moveanchor.png + +One can manually move anchors. Use a mouse pointer and hover above the end of an anchor. +Click the left button and then you can move selected anchor where ever you want. + +Selection +--------- + +Selection can be used to manually defined subgroups in the data. Use Shift +modifier when selecting data instances to put them into a new group. +Shift + Ctrl (or Shift + Cmd on macOs) appends instances to the last group. + +Signal data outputs a data table with an additional column that contains group +indices. + +.. figure:: images/FreeViz-selection.png + +Explorative Data Analysis +------------------------- + +The **FreeViz**, as the rest of Orange widgets, supports zooming-in and +out of part of the plot and a manual selection of data instances. +These functions are available in the lower left corner of the widget. +The default tool is *Select*, which selects data instances within the +chosen rectangular area. *Pan* enables you to move the plot around the pane. +With *Zoom* you can zoom in and out of the pane with a mouse scroll, +while *Reset zoom* resets the visualization to its optimal size. +An example of a simple schema, where we selected data instances from a +rectangular region and sent them to the :doc:`Data Table <../data/datatable>` +widget, is shown below. + +.. figure:: images/FreeViz-Example-Explorative.png diff --git a/doc/visual-programming/source/widgets/visualize/images/FreeViz-Example-Explorative.png b/doc/visual-programming/source/widgets/visualize/images/FreeViz-Example-Explorative.png new file mode 100644 index 0000000000000000000000000000000000000000..bea4bf56d6161593dd7b9488c97dab4303e0e31c GIT binary patch literal 81008 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

_SyDGu;~iMw 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 literal 0 HcmV?d00001 diff --git a/doc/visual-programming/source/widgets/visualize/images/freeviz-moveanchor.png b/doc/visual-programming/source/widgets/visualize/images/freeviz-moveanchor.png new file mode 100644 index 0000000000000000000000000000000000000000..8d9f3a956443cb28ad6ac2e902720a968d9f223a GIT binary patch literal 8754 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 literal 0 HcmV?d00001 diff --git a/doc/visual-programming/source/widgets/visualize/images/freeviz-zoo-stamped.png b/doc/visual-programming/source/widgets/visualize/images/freeviz-zoo-stamped.png new file mode 100644 index 0000000000000000000000000000000000000000..6e30e022833fb1ecd5fe60f6471e808786e29669 GIT binary patch literal 27838 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 V8(}t4I0*PtdaNc_Ci67t{{V4T;hq2h literal 0 HcmV?d00001 From 3e5774873b6af14a315b01c7b2792a434f0a81b3 Mon Sep 17 00:00:00 2001 From: Jernej Urankar Date: Wed, 11 Oct 2017 14:07:23 +0200 Subject: [PATCH 5/6] [ENH] FreeViz: new widget --- Orange/widgets/visualize/owfreeviz.py | 933 ++++++++++++++++++++++++++ 1 file changed, 933 insertions(+) create mode 100644 Orange/widgets/visualize/owfreeviz.py diff --git a/Orange/widgets/visualize/owfreeviz.py b/Orange/widgets/visualize/owfreeviz.py new file mode 100644 index 00000000000..389a826809c --- /dev/null +++ b/Orange/widgets/visualize/owfreeviz.py @@ -0,0 +1,933 @@ +from itertools import chain +import sys +from types import SimpleNamespace as namespace +from xml.sax.saxutils import escape + +from scipy.spatial import distance +import numpy as np + +from AnyQt.QtWidgets import ( + QFormLayout, QApplication, QGraphicsEllipseItem, QGraphicsSceneMouseEvent, QToolTip +) +from AnyQt.QtGui import QPen, QCursor +from AnyQt.QtCore import Qt, QObject, QEvent, QSize, QRectF, QLineF, QTimer, QPoint +from AnyQt.QtCore import pyqtSignal as Signal, pyqtSlot as Slot + +import pyqtgraph as pg + +from Orange.data import Table, Domain, StringVariable, ContinuousVariable +from Orange.projection.freeviz import FreeViz +from Orange.widgets import widget, gui, settings +from Orange.widgets.utils.annotated_data import ( + create_annotated_table, ANNOTATED_DATA_SIGNAL_NAME, create_groups_table +) +from Orange.widgets.visualize.owscatterplotgraph import OWScatterPlotGraph, InteractiveViewBox, \ + HelpEventDelegate +from Orange.widgets.visualize.utils.plotutils import AnchorItem +from Orange.widgets.widget import Input, Output +from Orange.canvas import report + + +class AsyncUpdateLoop(QObject): + """ + Run/drive an coroutine from the event loop. + + This is a utility class which can be used for implementing + asynchronous update loops. I.e. coroutines which periodically yield + control back to the Qt event loop. + + """ + Next = QEvent.registerEventType() + + #: State flags + Idle, Running, Cancelled, Finished = 0, 1, 2, 3 + #: The coroutine has yielded control to the caller (with `object`) + yielded = Signal(object) + #: The coroutine has finished/exited (either with an exception + #: or with a return statement) + finished = Signal() + + #: The coroutine has returned (normal return statement / StopIteration) + returned = Signal(object) + #: The coroutine has exited with with an exception. + raised = Signal(object) + #: The coroutine was cancelled/closed. + cancelled = Signal() + + def __init__(self, parent=None, **kwargs): + super().__init__(parent, **kwargs) + self.__coroutine = None + self.__next_pending = False # Flag for compressing scheduled events + self.__in_next = False + self.__state = AsyncUpdateLoop.Idle + + @Slot(object) + def setCoroutine(self, loop): + """ + Set the coroutine. + + The coroutine will be resumed (repeatedly) from the event queue. + If there is an existing coroutine set it is first closed/cancelled. + + Raises an RuntimeError if the current coroutine is running. + """ + if self.__coroutine is not None: + self.__coroutine.close() + self.__coroutine = None + self.__state = AsyncUpdateLoop.Cancelled + + self.cancelled.emit() + self.finished.emit() + + if loop is not None: + self.__coroutine = loop + self.__state = AsyncUpdateLoop.Running + self.__schedule_next() + + @Slot() + def cancel(self): + """ + Cancel/close the current coroutine. + + Raises an RuntimeError if the current coroutine is running. + """ + self.setCoroutine(None) + + def state(self): + """ + Return the current state. + """ + return self.__state + + def isRunning(self): + return self.__state == AsyncUpdateLoop.Running + + def __schedule_next(self): + if not self.__next_pending: + self.__next_pending = True + QTimer.singleShot(10, self.__on_timeout) + + def __next(self): + if self.__coroutine is not None: + try: + rval = next(self.__coroutine) + except StopIteration as stop: + self.__state = AsyncUpdateLoop.Finished + self.returned.emit(stop.value) + self.finished.emit() + self.__coroutine = None + except BaseException as er: + self.__state = AsyncUpdateLoop.Finished + self.raised.emit(er) + self.finished.emit() + self.__coroutine = None + else: + self.yielded.emit(rval) + self.__schedule_next() + + @Slot() + def __on_timeout(self): + assert self.__next_pending + self.__next_pending = False + if not self.__in_next: + self.__in_next = True + try: + self.__next() + finally: + self.__in_next = False + else: + # warn + self.__schedule_next() + + def customEvent(self, event): + if event.type() == AsyncUpdateLoop.Next: + self.__on_timeout() + else: + super().customEvent(event) + + +class FreeVizInteractiveViewBox(InteractiveViewBox): + def __init__(self, graph, enable_menu=False): + self.mousestate = 0 + self.point_i = None + self.cursor = QCursor() + super().__init__(graph, enable_menu) + + def _dragtip_pos(self): + return 10, 10 + + def mouseDragEvent(self, ev, axis=None): + master = self.graph.master + if master.data is None: + super().mouseDragEvent(ev, axis) + return + pos = self.childGroup.mapFromParent(ev.pos()) + minradius = master.radius / 100 + 1e-5 + points = master.plotdata.anchors + mask = np.zeros((len(points)), dtype=bool) + for i, point in enumerate(points): + if np.linalg.norm(point) > minradius: + mask[i] = True + np_pos = np.array([[pos.x(), pos.y()]]) + distances = distance.cdist(np_pos, points[:, :2])[0] + is_near = False if not len(distances[mask]) else np.min(distances[mask]) < 0.1 + + if ev.button() != Qt.LeftButton or (ev.start and not is_near): + self.mousestate = 2 # finished + if self.mousestate == 2: + if ev.finish: + self.mousestate = 0 # ready for new task + super().mouseDragEvent(ev, axis) + return + ev.accept() + if ev.start: + self.cursor.setShape(Qt.ClosedHandCursor) + self.mousestate = 1 # working + self.point_i = np.flatnonzero(mask)[np.argmin(distances[mask])] + master.randomize_indices() + is_moving = True + if self.mousestate == 1: + if ev.finish: + self.cursor.setShape(Qt.OpenHandCursor) + self.mousestate = 0 + is_moving = False + points[self.point_i][0] = pos.x() + points[self.point_i][1] = pos.y() + if is_moving: + master.manual_move_anchor() + else: + master.setup_plot(reset_view=False) + self.graph.show_indicator(point_i=self.point_i) + self.setCursor(self.cursor) + + +class EventDelegate(HelpEventDelegate): + def __init__(self, delegate, delegate2, parent=None): + self.delegate2 = delegate2 + super().__init__(delegate, parent=parent) + + def eventFilter(self, obj, ev): + if isinstance(ev, QGraphicsSceneMouseEvent): + self.delegate2(ev) + return super().eventFilter(obj, ev) + + +SELECTION_WIDTH = 5 +RANGE = QRectF(-1.05, -1.05, 2.1, 2.1) + +class OWFreeVizGraph(OWScatterPlotGraph): + jitter_size = settings.Setting(0) + + def __init__(self, scatter_widget, parent=None, name="None", view_box=None): + super().__init__(scatter_widget, parent=parent, _=name, view_box=view_box) + self._tooltip_delegate = EventDelegate(self.help_event, self._show_indicator) + self.plot_widget.scene().installEventFilter(self._tooltip_delegate) + self.master = scatter_widget + for axis_loc in ["left", "bottom"]: + self.plot_widget.hideAxis(axis_loc) + + def update_data(self, attr_x, attr_y, reset_view=True): + super().update_data(attr_x, attr_y, reset_view=reset_view) + for axis in ["left", "bottom"]: + self.plot_widget.hideAxis(axis) + + if reset_view: + self.view_box.setRange( + RANGE, + padding=0.025) + self.master.viewbox.setAspectLocked(True, 1) + self.master.viewbox.init_history() + self.master.viewbox.tag_history() + + def _show_indicator(self, ev): + scene = self.plot_widget.scene() + if self.scatterplot_item is None or scene.drag_tooltip.isVisible(): + return False + + for indicator in self.master.plotdata.indicators: + self.plot_widget.removeItem(indicator) + self.master.plotdata.indicators = [] + pos = self.scatterplot_item.mapFromScene(ev.scenePos()) + x = pos.x() + y = pos.y() + master = self.master + minradius = master.radius / 100 + 1e-5 + points = master.plotdata.anchors + mask = np.zeros((len(points)), dtype=bool) + for i, point in enumerate(points): + if np.linalg.norm(point) > minradius: + mask[i] = True + np_pos = np.array([[x, y]]) + distances = distance.cdist(np_pos, points[:, :2])[0] + if len(distances[mask]) and np.min(distances[mask]) < 0.08: + if self.view_box.mousestate == 0: + self.view_box.cursor.setShape(Qt.OpenHandCursor) + self.show_indicator(point_i=np.flatnonzero(mask)[np.argmin(distances[mask])]) + else: + self.view_box.cursor.setShape(Qt.ArrowCursor) + self.view_box.setCursor(self.view_box.cursor) + return True + + def show_indicator(self, point_i): + points = self.master.plotdata.anchors + func = self.view_box.childGroup.mapToDevice + dx = (func(QPoint(1, 0)) - func(QPoint(-1, 0))).x() + scene_size = 600 / dx + self.master.plotdata.indicators.append( + MoveIndicator(points[point_i][0], points[point_i][1], scene_size=scene_size) + ) + self.plot_widget.addItem(self.master.plotdata.indicators[0]) + + def help_event(self, event): + if self.scatterplot_item is None: + return False + + act_pos = self.scatterplot_item.mapFromScene(event.scenePos()) + points = self.scatterplot_item.pointsAt(act_pos) + text = "" + attr = lambda i: self.domain.attributes[i] + if len(points): + for i, p in enumerate(points): + index = p.data() + text += "Attributes:\n" + text += "".join( + " {} = {}\n".format(attr(i).name, + self.data[index][attr(i)]) + for i in self.master.plotdata.topattrs[index]) + if len(self.domain.attributes) > 10: + text += " ... and {} others\n\n".format(len(self.domain.attributes) - 12) + # class_var is always: + text += "Class:\n {} = {}\n".format(self.domain.class_var.name, + self.data[index][self.data.domain.class_var]) + if i < len(points) - 1: + text += '------------------\n' + text = ('{}'.format(escape(text))) + + QToolTip.showText(event.screenPos(), text, widget=self.plot_widget) + return True + else: + return False + +MAX_ITERATIONS = 1000 +MAX_ANCHORS = 20 +MAX_POINTS = 300 +MAX_INSTANCES = 10000 + + +class OWFreeViz(widget.OWWidget): + name = "FreeViz" + description = "Displays FreeViz projection" + icon = "icons/Freeviz.svg" + priority = 240 + + class Inputs: + data = Input("Data", Table, default=True) + data_subset = Input("Data Subset", Table) + + class Outputs: + selected_data = Output("Selected Data", Table, default=True) + annotated_data = Output(ANNOTATED_DATA_SIGNAL_NAME, Table) + components = Output("Components", Table) + + #: Initialization type + Circular, Random = 0, 1 + + jitter_sizes = [0, 0.1, 0.5, 1, 2] + + settings_version = 2 + settingsHandler = settings.DomainContextHandler() + + radius = settings.Setting(0) + initialization = settings.Setting(Circular) + auto_commit = settings.Setting(True) + + resolution = 256 + graph = settings.SettingProvider(OWFreeVizGraph) + + ReplotRequest = QEvent.registerEventType() + + graph_name = "graph.plot_widget.plotItem" + + + class Warning(widget.OWWidget.Warning): + sparse_not_supported = widget.Msg("Sparse data is ignored.") + + class Error(widget.OWWidget.Error): + no_class_var = widget.Msg("Need a class variable") + not_enough_class_vars = widget.Msg("Needs discrete class variable " \ + "with at lest 2 values") + features_exceeds_instances = widget.Msg("Algorithm should not be used when " \ + "number of features exceeds the number " \ + "of instances.") + too_many_data_instances = widget.Msg("Cannot handle so large data.") + no_valid_data = widget.Msg("No valid data.") + + + def __init__(self): + super().__init__() + + self.data = None + self.subset_data = None + self._subset_mask = None + self._validmask = None + self._X = None + self._Y = None + self._selection = None + self.__replot_requested = False + + self.variable_x = ContinuousVariable("freeviz-x") + self.variable_y = ContinuousVariable("freeviz-y") + + box0 = gui.vBox(self.mainArea, True, margin=0) + self.graph = OWFreeVizGraph(self, box0, "Plot", view_box=FreeVizInteractiveViewBox) + box0.layout().addWidget(self.graph.plot_widget) + plot = self.graph.plot_widget + + box = gui.widgetBox(self.controlArea, "Optimization", spacing=10) + form = QFormLayout( + labelAlignment=Qt.AlignLeft, + formAlignment=Qt.AlignLeft, + fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow, + verticalSpacing=10 + ) + form.addRow( + "Initialization", + gui.comboBox(box, self, "initialization", + items=["Circular", "Random"], + callback=self.reset_initialization) + ) + box.layout().addLayout(form) + + self.btn_start = gui.button(widget=box, master=self, label="Optimize", + callback=self.toogle_start, enabled=False) + + self.viewbox = plot.getViewBox() + self.replot = None + + g = self.graph.gui + g.point_properties_box(self.controlArea) + self.models = g.points_models + + box = gui.widgetBox(self.controlArea, "Show anchors") + self.rslider = gui.hSlider( + box, self, "radius", minValue=0, maxValue=100, + step=5, label="Radius", createLabel=False, ticks=True, + callback=self.update_radius) + self.rslider.setTickInterval(0) + self.rslider.setPageStep(10) + + box = gui.vBox(self.controlArea, "Plot Properties") + + g.add_widgets([g.JitterSizeSlider], box) + g.add_widgets([g.ShowLegend, + g.ClassDensity, + g.LabelOnlySelected], + box) + + self.graph.box_zoom_select(self.controlArea) + self.controlArea.layout().addStretch(100) + self.icons = gui.attributeIconDict + + p = self.graph.plot_widget.palette() + self.graph.set_palette(p) + + gui.auto_commit(self.controlArea, self, "auto_commit", + "Send Selection", "Send Automatically") + self.graph.zoom_actions(self) + # FreeViz + self._loop = AsyncUpdateLoop(parent=self) + self._loop.yielded.connect(self.__set_projection) + self._loop.finished.connect(self.__freeviz_finished) + self._loop.raised.connect(self.__on_error) + + self._new_plotdata() + + def keyPressEvent(self, event): + super().keyPressEvent(event) + self.graph.update_tooltip(event.modifiers()) + + def keyReleaseEvent(self, event): + super().keyReleaseEvent(event) + self.graph.update_tooltip(event.modifiers()) + + def update_radius(self): + # Update the anchor/axes visibility + assert not self.plotdata is None + + minradius = self.radius / 100 + 1e-5 + for anchor, item in zip(self.plotdata.anchors, + self.plotdata.anchoritem): + item.setVisible(np.linalg.norm(anchor) > minradius) + self.plotdata.hidecircle.setRect( + QRectF(-minradius, -minradius, + 2 * minradius, 2 * minradius)) + + def toogle_start(self): + if self._loop.isRunning(): + self._loop.cancel() + if isinstance(self, OWFreeViz): + self.btn_start.setText("Optimize") + self.progressBarFinished(processEvents=False) + else: + self._start() + + def _start(self): + """ + Start the projection optimization. + """ + assert not self.plotdata is None + + X, Y = self.plotdata.X, self.plotdata.Y + anchors = self.plotdata.anchors + + def update_freeviz(interval, initial): + anchors = initial + while True: + res = FreeViz.freeviz(X, Y, scale=False, center=False, + initial=anchors, maxiter=interval) + _, anchors_new = res[:2] + yield res[:2] + if np.allclose(anchors, anchors_new, rtol=1e-5, atol=1e-4): + return + + anchors = anchors_new + + interval = 10 # TODO + + self._loop.setCoroutine( + update_freeviz(interval, anchors)) + self.btn_start.setText("Stop") + self.progressBarInit(processEvents=False) + self.setBlocking(True) + self.setStatusMessage("Optimizing") + + def reset_initialization(self): + """ + Reset the current 'anchor' initialization, and restart the + optimization if necessary. + """ + running = self._loop.isRunning() + + if running: + self._loop.cancel() + + if self.data is not None: + self._clear_plot() + self.setup_plot() + + if running: + self._start() + + def __set_projection(self, res): + # Set/update the projection matrix and coordinate embeddings + # assert self.plotdata is not None, "__set_projection call unexpected" + assert not self.plotdata is None + increment = 1 # TODO + self.progressBarAdvance( + increment * 100. / MAX_ITERATIONS, processEvents=False) # TODO + embedding_coords, projection = res + self.plotdata.embedding_coords = embedding_coords + self.plotdata.anchors = projection + self._update_xy() + self.update_radius() + self.update_density() + + def __freeviz_finished(self): + # Projection optimization has finished + self.btn_start.setText("Optimize") + self.setStatusMessage("") + self.setBlocking(False) + self.progressBarFinished(processEvents=False) + self.commit() + + def __on_error(self, err): + sys.excepthook(type(err), err, getattr(err, "__traceback__")) + + def _update_xy(self): + # Update the plotted embedding coordinates + self.graph.plot_widget.clear() + coords = self.plotdata.embedding_coords + radius = np.max(np.linalg.norm(coords, axis=1)) + self.plotdata.embedding_coords = coords / radius + self.plot(show_anchors=(len(self.data.domain.attributes) < MAX_ANCHORS)) + + def _new_plotdata(self): + self.plotdata = namespace( + validmask=None, + embedding_coords=None, + anchors=[], + anchoritem=[], + X=None, + Y=None, + indicators=[], + hidecircle=None, + data=None, + items=[], + topattrs=None, + rand=None, + selection=None, # np.array + ) + + def _anchor_circle(self): + # minimum visible anchor radius (radius) + minradius = self.radius / 100 + 1e-5 + for item in chain(self.plotdata.anchoritem, self.plotdata.items): + self.viewbox.removeItem(item) + self.plotdata.anchoritem = [] + self.plotdata.items = [] + for anchor, var in zip(self.plotdata.anchors, self.data.domain.attributes): + if True or np.linalg.norm(anchor) > minradius: + axitem = AnchorItem( + line=QLineF(0, 0, *anchor), text=var.name,) + axitem.setVisible(np.linalg.norm(anchor) > minradius) + axitem.setPen(pg.mkPen((100, 100, 100))) + axitem.setArrowVisible(True) + self.plotdata.anchoritem.append(axitem) + self.viewbox.addItem(axitem) + + hidecircle = QGraphicsEllipseItem() + hidecircle.setRect( + QRectF(-minradius, -minradius, + 2 * minradius, 2 * minradius)) + + _pen = QPen(Qt.lightGray, 1) + _pen.setCosmetic(True) + hidecircle.setPen(_pen) + self.viewbox.addItem(hidecircle) + self.plotdata.items.append(hidecircle) + self.plotdata.hidecircle = hidecircle + + def update_colors(self): + pass + + def sizeHint(self): + return QSize(800, 500) + + def _clear(self): + """ + Clear/reset the widget state + """ + self._loop.cancel() + self.data = None + self._selection = None + self._clear_plot() + + def _clear_plot(self): + for item in chain(self.plotdata.anchoritem, self.plotdata.items): + self.viewbox.removeItem(item) + self.graph.plot_widget.clear() + self._new_plotdata() + + def init_attr_values(self): + domain = self.data and len(self.data) and self.data.domain or None + for model in self.models: + model.set_domain(domain) + self.graph.attr_label = None + self.graph.attr_size = None + self.graph.attr_shape = None + self.graph.attr_color = self.data.domain.class_var if domain else None + + @Inputs.data + def set_data(self, data): + self.clear_messages() + self._clear() + self.closeContext() + if data is not None: + if data and data.is_sparse(): + self.Warning.sparse_not_supported() + data = None + elif data.domain.class_var is None: + self.Error.no_class_var() + data = None + elif data.domain.class_var.is_discrete and \ + len(data.domain.class_var.values) < 2: + self.Error.not_enough_class_vars() + data = None + if data and len(data.domain.attributes) > data.X.shape[0]: + self.Error.features_exceeds_instances() + data = None + if data is not None: + valid_instances_count = self._prepare_freeviz_data(data) + if valid_instances_count > MAX_INSTANCES: + self.Error.too_many_data_instances() + data = None + elif valid_instances_count == 0: + self.Error.no_valid_data() + data = None + self.data = data + self.init_attr_values() + if data is not None: + self.cb_class_density.setEnabled(data.domain.has_discrete_class) + self.openContext(data) + self.btn_start.setEnabled(True) + else: + self.btn_start.setEnabled(False) + self._X = self._Y = None + self.graph.new_data(None, None) + + @Inputs.data_subset + def set_subset_data(self, subset): + self.subset_data = subset + self.plotdata.subset_mask = None + self.controls.graph.alpha_value.setEnabled(subset is None) + + def handleNewSignals(self): + if all(v is not None for v in [self.data, self.subset_data]): + dataids = self.data.ids.ravel() + subsetids = np.unique(self.subset_data.ids) + self._subset_mask = np.in1d(dataids, subsetids, assume_unique=True) + if self._X is not None: + self.setup_plot(True) + self.commit() + + def customEvent(self, event): + if event.type() == OWFreeViz.ReplotRequest: + self.__replot_requested = False + self.setup_plot() + else: + super().customEvent(event) + + def _prepare_freeviz_data(self, data): + X = data.X + Y = data.Y + mask = np.bitwise_or.reduce(np.isnan(X), axis=1) + mask |= np.isnan(Y) + validmask = ~mask + X = X[validmask, :] + Y = Y[validmask] + + if not len(X): + self._X = None + return 0 + + if data.domain.class_var.is_discrete: + Y = Y.astype(int) + X = (X - np.mean(X, axis=0)) + span = np.ptp(X, axis=0) + X[:, span > 0] /= span[span > 0].reshape(1, -1) + self._X = X + self._Y = Y + self._validmask = validmask + return len(X) + + def setup_plot(self, reset_view=True): + assert not self._X is None + + self.graph.jitter_continuous = True + self.__replot_requested = False + + X = self.plotdata.X = self._X + self.plotdata.Y = self._Y + self.plotdata.validmask = self._validmask + self.plotdata.selection = self._selection if self._selection is not None else \ + np.zeros(len(self._validmask), dtype=np.uint8) + anchors = self.plotdata.anchors + if len(anchors) == 0: + if self.initialization == self.Circular: + anchors = FreeViz.init_radial(X.shape[1]) + else: + anchors = FreeViz.init_random(X.shape[1], 2) + + EX = np.dot(X, anchors) + c = np.zeros((X.shape[0], X.shape[1])) + for i in range(X.shape[0]): + c[i] = np.argsort((np.power(X[i] * anchors[:, 0], 2) + + np.power(X[i] * anchors[:, 1], 2)))[::-1] + self.plotdata.topattrs = np.array(c, dtype=int)[:, :10] + radius = np.max(np.linalg.norm(EX, axis=1)) + + self.plotdata.anchors = anchors + + coords = (EX / radius) + self.plotdata.embedding_coords = coords + if reset_view: + self.viewbox.setRange(RANGE) + self.viewbox.setAspectLocked(True, 1) + self.plot(reset_view=reset_view) + + def randomize_indices(self): + X = self._X + self.plotdata.rand = np.random.choice(len(X), MAX_POINTS, replace=False) \ + if len(X) > MAX_POINTS else None + + def manual_move_anchor(self, show_anchors=True): + self.__replot_requested = False + X = self.plotdata.X = self._X + anchors = self.plotdata.anchors + validmask = self.plotdata.validmask + EX = np.dot(X, anchors) + data_x = self.data.X[validmask] + data_y = self.data.Y[validmask] + radius = np.max(np.linalg.norm(EX, axis=1)) + if self.plotdata.rand is not None: + rand = self.plotdata.rand + EX = EX[rand] + data_x = data_x[rand] + data_y = data_y[rand] + selection = self.plotdata.selection[validmask] + selection = selection[rand] + else: + selection = self.plotdata.selection[validmask] + coords = (EX / radius) + + if show_anchors: + self._anchor_circle() + attributes = () + self.data.domain.attributes + (self.variable_x, self.variable_y) + domain = Domain(attributes=attributes, + class_vars=self.data.domain.class_vars) + data = Table.from_numpy(domain, X=np.hstack((data_x, coords)), + Y=data_y) + self.graph.new_data(data, None) + self.graph.selection = selection + self.graph.update_data(self.variable_x, self.variable_y, reset_view=False) + + def plot(self, reset_view=False, show_anchors=True): + if show_anchors: + self._anchor_circle() + attributes = () + self.data.domain.attributes + (self.variable_x, self.variable_y) + domain = Domain(attributes=attributes, + class_vars=self.data.domain.class_vars, + metas=self.data.domain.metas) + mask = self.plotdata.validmask + array = np.zeros((len(self.data), 2), dtype=np.float) + array[mask] = self.plotdata.embedding_coords + data = Table.from_numpy(domain, X=np.hstack((self.data.X, array)), + Y=self.data.Y, + metas=self.data.metas) + subset_data = data[self._subset_mask & mask]\ + if self._subset_mask is not None and len(self._subset_mask) else None + self.plotdata.data = data + self.graph.new_data(data[mask], subset_data) + if self.plotdata.selection is not None: + self.graph.selection = self.plotdata.selection[self.plotdata.validmask] + self.graph.update_data(self.variable_x, self.variable_y, reset_view=reset_view) + + def reset_graph_data(self, *_): + if self.data is not None: + self.graph.rescale_data() + self._update_graph() + + def _update_graph(self, reset_view=True, **_): + self.graph.zoomStack = [] + assert not self.graph.data is None + self.graph.update_data(self.variable_x, self.variable_y, reset_view) + + def update_density(self): + self._update_graph(reset_view=False) + + def selection_changed(self): + if self.graph.selection is not None: + pd = self.plotdata + pd.selection[pd.validmask] = self.graph.selection + self._selection = pd.selection + self.commit() + + def prepare_data(self): + pass + + def commit(self): + selected = annotated = components = None + graph = self.graph + if self.data is not None and self.plotdata.validmask is not None: + name = self.data.name + metas = () + self.data.domain.metas + (self.variable_x, self.variable_y) + domain = Domain(attributes=self.data.domain.attributes, + class_vars=self.data.domain.class_vars, + metas=metas) + data = self.plotdata.data.transform(domain) + validmask = self.plotdata.validmask + mask = np.array(validmask, dtype=int) + mask[mask == 1] = graph.selection if graph.selection is not None \ + else [False * len(mask)] + selection = np.array([], dtype=np.uint8) if mask is None else np.flatnonzero(mask) + if len(selection): + selected = data[selection] + selected.name = name + ": selected" + selected.attributes = self.data.attributes + if graph.selection is not None and np.max(graph.selection) > 1: + annotated = create_groups_table(data, mask) + else: + annotated = create_annotated_table(data, selection) + annotated.attributes = self.data.attributes + annotated.name = name + ": annotated" + + comp_domain = Domain( + self.data.domain.attributes, + metas=[StringVariable(name='component')]) + + metas = np.array([["FreeViz 1"], ["FreeViz 2"]]) + components = Table.from_numpy( + comp_domain, + X=self.plotdata.anchors.T, + metas=metas) + + components.name = name + ": components" + + self.Outputs.selected_data.send(selected) + self.Outputs.annotated_data.send(annotated) + self.Outputs.components.send(components) + + def send_report(self): + if self.data is None: + return + + def name(var): + return var and var.name + + caption = report.render_items_vert(( + ("Color", name(self.graph.attr_color)), + ("Label", name(self.graph.attr_label)), + ("Shape", name(self.graph.attr_shape)), + ("Size", name(self.graph.attr_size)), + ("Jittering", self.graph.jitter_size != 0 and "{} %".format(self.graph.jitter_size)))) + self.report_plot() + if caption: + self.report_caption(caption) + + +class MoveIndicator(pg.GraphicsObject): + def __init__(self, x, y, parent=None, line=QLineF(), scene_size=1, text="", **kwargs): + super().__init__(parent, **kwargs) + self.arrows = [ + pg.ArrowItem(pos=(x - scene_size * 0.07 * np.cos(np.radians(angle)), + y + scene_size * 0.07 * np.sin(np.radians(angle))), + parent=self, angle=angle, + headLen=13, tipAngle=45, + brush=pg.mkColor(128, 128, 128)) + for angle in (0, 90, 180, 270)] + + def paint(self, painter, option, widget): + pass + + def boundingRect(self): + return QRectF() + + +def main(argv=None): + import sip + + argv = sys.argv[1:] if argv is None else argv + if argv: + filename = argv[0] + else: + filename = "zoo" + + data = Table(filename) + + app = QApplication([]) + w = OWFreeViz() + w.set_data(data) + w.set_subset_data(data[::10]) + w.handleNewSignals() + w.show() + w.raise_() + r = app.exec() + w.set_data(None) + w.saveSettings() + sip.delete(w) + del w + return r + + +if __name__ == "__main__": + sys.exit(main()) From 1ff9c6be141fa30618000abb65e0b13a03d22729 Mon Sep 17 00:00:00 2001 From: Jernej Urankar Date: Wed, 11 Oct 2017 14:07:23 +0200 Subject: [PATCH 6/6] FreeViz: tests --- .../widgets/visualize/tests/test_owfreeviz.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Orange/widgets/visualize/tests/test_owfreeviz.py diff --git a/Orange/widgets/visualize/tests/test_owfreeviz.py b/Orange/widgets/visualize/tests/test_owfreeviz.py new file mode 100644 index 00000000000..35db2cfd2a4 --- /dev/null +++ b/Orange/widgets/visualize/tests/test_owfreeviz.py @@ -0,0 +1,108 @@ +# Test methods with long descriptive names can omit docstrings +# pylint: disable=missing-docstring +import scipy.sparse as sp + +from AnyQt.QtCore import QRectF, QPointF + +from Orange.data import Table, Domain, ContinuousVariable, DiscreteVariable +from Orange.widgets.tests.utils import simulate +from Orange.widgets.visualize.owfreeviz import OWFreeViz +from Orange.widgets.tests.base import WidgetTest, WidgetOutputsTestMixin, \ + datasets + + +class TestOWFreeViz(WidgetTest, WidgetOutputsTestMixin): + @classmethod + def setUpClass(cls): + super().setUpClass() + WidgetOutputsTestMixin.init(cls) + + cls.signal_name = "Data" + cls.signal_data = cls.data + cls.same_input_output_domain = False + cls.heart_disease = Table("heart_disease") + + def setUp(self): + self.widget = self.create_widget(OWFreeViz) + + def test_points_combo_boxes(self): + self.send_signal(self.widget.Inputs.data, self.heart_disease) + graph = self.widget.controls.graph + self.assertEqual(len(graph.attr_color.model()), 17) + self.assertEqual(len(graph.attr_shape.model()), 11) + self.assertEqual(len(graph.attr_size.model()), 8) + self.assertEqual(len(graph.attr_label.model()), 17) + + def test_ugly_datasets(self): + self.send_signal(self.widget.Inputs.data, Table(datasets.path("testing_dataset_cls"))) + self.send_signal(self.widget.Inputs.data, Table(datasets.path("testing_dataset_reg"))) + + def test_error_msg(self): + data = self.data[:, list(range(len(self.data.domain.attributes)))] + self.assertFalse(self.widget.Error.no_class_var.is_shown()) + self.assertFalse(self.widget.Error.not_enough_class_vars.is_shown()) + self.send_signal(self.widget.Inputs.data, data) + self.assertTrue(self.widget.Error.no_class_var.is_shown()) + data = self.data[:40] + data.domain.class_var.values = data.domain.class_var.values[0:1] + data = data.transform(self.data.domain) + self.send_signal(self.widget.Inputs.data, data) + self.assertTrue(self.widget.Error.not_enough_class_vars.is_shown()) + self.send_signal(self.widget.Inputs.data, None) + self.assertFalse(self.widget.Error.no_class_var.is_shown()) + self.assertFalse(self.widget.Error.not_enough_class_vars.is_shown()) + + def _select_data(self): + self.widget.graph.select_by_rectangle(QRectF(QPointF(-20, -20), QPointF(20, 20))) + return self.widget.graph.get_selection() + + def test_optimization(self): + self.send_signal(self.widget.Inputs.data, Table("iris")) + self.widget.btn_start.click() + + def test_optimization_cancelled(self): + self.test_optimization() + self.widget.btn_start.click() + + def test_reset_optimization(self): + self.send_signal(self.widget.Inputs.data, Table("iris")) + simulate.combobox_activate_index(self.widget.controls.initialization, 0) + simulate.combobox_activate_index(self.widget.controls.initialization, 1) + + def test_size_hint(self): + self.widget.show() + + def test_send_report(self): + self.send_signal(self.widget.Inputs.data, Table("iris")) + self.widget.report_button.click() + self.send_signal(self.widget.Inputs.data, None) + self.widget.report_button.click() + + def test_subset_data(self): + self.send_signal(self.widget.Inputs.data, self.heart_disease) + self.send_signal(self.widget.Inputs.data_subset, self.heart_disease) + + def test_sparse(self): + table = Table("iris") + table.X = sp.csr_matrix(table.X) + self.assertTrue(sp.issparse(table.X)) + self.assertFalse(self.widget.Warning.sparse_not_supported.is_shown()) + self.send_signal(self.widget.Inputs.data, table) + self.assertTrue(self.widget.Warning.sparse_not_supported.is_shown()) + + def test_none_data(self): + table = Table( + Domain( + [ContinuousVariable("a"), + DiscreteVariable("b", values=["y", "n"])] + ), + list(zip( + [], + "")) + ) + self.send_signal(self.widget.Inputs.data, table) + self.widget.reset_graph_data() + + def test_class_density(self): + self.send_signal(self.widget.Inputs.data, Table("iris")) + self.widget.cb_class_density.click()