Skip to content

Commit

Permalink
Merge pull request #2656 from ales-erjavec/fixes/silhouette-plot-prox…
Browse files Browse the repository at this point in the history
…y-widget

[FIX] Silhouette plot rendering
  • Loading branch information
janezd authored Oct 13, 2017
2 parents 8534e2a + e7da4ed commit 9157034
Showing 1 changed file with 81 additions and 18 deletions.
99 changes: 81 additions & 18 deletions Orange/widgets/visualize/owsilhouetteplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
from xml.sax.saxutils import escape
from types import SimpleNamespace as namespace

if sys.version_info > (3, 5):
from typing import Optional
from typing import Optional

import numpy as np
import sklearn.metrics

from AnyQt.QtWidgets import (
QGraphicsScene, QGraphicsView, QGraphicsWidget, QGraphicsGridLayout,
QGraphicsProxyWidget, QGraphicsItemGroup, QGraphicsSimpleTextItem,
QGraphicsRectItem, QFrame, QSizePolicy
QGraphicsItemGroup, QGraphicsSimpleTextItem, QGraphicsRectItem,
QSizePolicy, QStyleOptionGraphicsItem, QWidget, QWIDGETSIZE_MAX
)
from AnyQt.QtGui import QColor, QPen, QBrush, QPainter, QFontMetrics
from AnyQt.QtGui import QColor, QPen, QBrush, QPainter, QFontMetrics, QPalette
from AnyQt.QtCore import Qt, QEvent, QRectF, QSizeF, QSize, QPointF
from AnyQt.QtCore import pyqtSignal as Signal

Expand Down Expand Up @@ -327,20 +326,14 @@ def _replot(self):

self.scene.addItem(silplot)
self._update_annotations()

silplot.resize(silplot.effectiveSizeHint(Qt.PreferredSize))
silplot.selectionChanged.connect(self.commit)

self.scene.setSceneRect(
QRectF(QPointF(0, 0),
self._silplot.effectiveSizeHint(Qt.PreferredSize)))
silplot.layout().activate()
self._update_scene_rect()
silplot.geometryChanged.connect(self._update_scene_rect)

def _update_bar_size(self):
if self._silplot is not None:
self._set_bar_height()
self.scene.setSceneRect(
QRectF(QPointF(0, 0),
self._silplot.effectiveSizeHint(Qt.PreferredSize)))

def _update_annotations(self):
if 0 < self.annotation_var_idx < len(self.annotation_var_model):
Expand All @@ -361,6 +354,9 @@ def _update_annotations(self):
else:
self._silplot.setRowNames(None)

def _update_scene_rect(self):
self.scene.setSceneRect(self._silplot.geometry())

def commit(self):
"""
Commit/send the current selection to the output.
Expand Down Expand Up @@ -542,6 +538,7 @@ def setRowNamesVisible(self, visible):
self.__rowNamesVisible = visible
for item in self.__textItems():
item.setVisible(visible)
self.updateGeometry()

def rowNamesVisible(self):
return self.__rowNamesVisible
Expand Down Expand Up @@ -608,10 +605,7 @@ def __setup(self):
self.layout().addItem(silhouettegroup, i + 1, 2)

if group.label:
line = QFrame(frameShape=QFrame.VLine)
proxy = QGraphicsProxyWidget(self)
proxy.setWidget(line)
self.layout().addItem(proxy, i + 1, 1)
self.layout().addItem(Line(orientation=Qt.Vertical), i + 1, 1)
label = QGraphicsSimpleTextItem(self)
label.setText("{} ({})".format(escape(group.label),
len(group.scores)))
Expand Down Expand Up @@ -893,6 +887,75 @@ def selection(self):
return np.asarray(self.__selection, dtype=int)


class Line(QGraphicsWidget):
"""
A line separator graphics widget
"""
def __init__(self, parent=None, orientation=Qt.Horizontal, **kwargs):
sizePolicy = kwargs.pop("sizePolicy", None)
super().__init__(None, **kwargs)
self.__orientation = Qt.Horizontal
if sizePolicy is None:
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
sizePolicy.setControlType(QSizePolicy.Frame)
self.setSizePolicy(sizePolicy)
else:
self.setSizePolicy(sizePolicy)

self.setOrientation(orientation)

if parent is not None:
self.setParentItem(parent)

def setOrientation(self, orientation):
if self.__orientation != orientation:
self.__orientation = orientation
sp = self.sizePolicy()
if orientation == Qt.Vertical:
sp.setVerticalPolicy(QSizePolicy.Expanding)
sp.setHorizontalPolicy(QSizePolicy.Fixed)
else:
sp.setVerticalPolicy(QSizePolicy.Fixed)
sp.setHorizontalPolicy(QSizePolicy.Expanding)
self.setSizePolicy(sp)
self.updateGeometry()

def sizeHint(self, which, constraint=QRectF()):
# type: (Qt.SizeHint, QSizeF) -> QSizeF
pw = 1.
sh = QSizeF()
if which == Qt.MinimumSize:
sh = QSizeF(pw, pw)
elif which == Qt.PreferredSize:
sh = QSizeF(pw, 30.)
elif which == Qt.MaximumSize:
sh = QSizeF(pw, QWIDGETSIZE_MAX)

if self.__orientation == Qt.Horizontal:
sh = sh.transposed()
return sh

def paint(self, painter, option, widget=None):
# type: (QPainter, QStyleOptionGraphicsItem, Optional[QWidget]) -> None
palette = option.palette # type: QPalette
role = QPalette.WindowText
if widget is not None:
role = widget.foregroundRole()
color = palette.color(role)
painter.setPen(QPen(color, 1))
rect = self.contentsRect()
center = rect.center()
if self.__orientation == Qt.Vertical:
p1 = QPointF(center.x(), rect.top())
p2 = QPointF(center.x(), rect.bottom())
elif self.__orientation == Qt.Horizontal:
p1 = QPointF(rect.left(), center.y())
p2 = QPointF(rect.right(), center.y())
else:
assert False
painter.drawLine(p1, p2)


class BarPlotItem(QGraphicsWidget):
def __init__(self, parent=None, **kwargs):
super().__init__(parent, **kwargs)
Expand Down

0 comments on commit 9157034

Please sign in to comment.