class ImageColorLegend(GraphicsWidget): def __init__(self): GraphicsWidget.__init__(self) self.width_bar = 15 self.colors = None self.gradient = QLinearGradient() self.setMaximumHeight(2**16) self.setMinimumWidth(self.width_bar) self.setMaximumWidth(self.width_bar) self.rect = QGraphicsRectItem(QRectF(0, 0, self.width_bar, 100), self) self.axis = pg.AxisItem('right', parent=self) self.axis.setX(self.width_bar) self.axis.geometryChanged.connect(self._update_width) self.adapt_to_size() self._initialized = True def _update_width(self): aw = self.axis.minimumWidth() self.setMinimumWidth(self.width_bar + aw) self.setMaximumWidth(self.width_bar + aw) def resizeEvent(self, ev): if hasattr(self, "_initialized"): self.adapt_to_size() def adapt_to_size(self): h = self.height() self.resetTransform() self.rect.setRect(0, 0, self.width_bar, h) self.axis.setHeight(h) self.gradient.setStart(QPointF(0, h)) self.gradient.setFinalStop(QPointF(0, 0)) self.update_rect() def set_colors(self, colors): # a Nx3 array containing colors self.colors = colors if self.colors is not None: positions = np.linspace(0, 1, len(self.colors)) stops = [] for p, c in zip(positions, self.colors): stops.append((p, QColor(*c))) self.gradient.setStops(stops) self.update_rect() def set_range(self, low, high): self.axis.setRange(low, high) def update_rect(self): if self.colors is None: self.rect.setBrush(QBrush(Qt.white)) else: self.rect.setBrush(QBrush(self.gradient))
class LegendGradient(QGraphicsWidget): """Gradient widget. A gradient square bar that can be used to display continuous values. Parameters ---------- palette : iterable[QColor] parent : QGraphicsWidget orientation : Qt.Orientation Notes ----- .. note:: While the gradient does support any number of colors, any more than 3 is not very readable. This should not be a problem, since Orange only implements 2 or 3 colors. """ # Default sizes (assume gradient is vertical by default) GRADIENT_WIDTH = 20 GRADIENT_HEIGHT = 150 _size_hint = QSizeF(GRADIENT_WIDTH, GRADIENT_HEIGHT) def __init__(self, palette, parent, orientation): super().__init__(parent) self.__gradient = QLinearGradient() num_colors = len(palette) for idx, stop in enumerate(palette): self.__gradient.setColorAt(idx * (1. / (num_colors - 1)), stop) # We need to tell the gradient where it's start and stop points are self.__gradient.setStart(QPointF(0, 0)) if orientation == Qt.Vertical: final_stop = QPointF(0, self.GRADIENT_HEIGHT) else: final_stop = QPointF(self.GRADIENT_HEIGHT, 0) self.__gradient.setFinalStop(final_stop) # Get the appropriate rectangle dimensions based on orientation if orientation == Qt.Vertical: width, height = self.GRADIENT_WIDTH, self.GRADIENT_HEIGHT elif orientation == Qt.Horizontal: width, height = self.GRADIENT_HEIGHT, self.GRADIENT_WIDTH self.__rect_item = QGraphicsRectItem(0, 0, width, height, self) self.__rect_item.setPen(QPen(QColor(0, 0, 0, 0))) self.__rect_item.setBrush(QBrush(self.__gradient)) self._size_hint = QSizeF(self.__rect_item.boundingRect().size()) def sizeHint(self, size_hint, size_constraint=None, *args, **kwargs): return self._size_hint
class OWLegendGradient(QGraphicsObject): gradient_width = 20 def __init__(self, palette, values, parent): QGraphicsObject.__init__(self, parent) self.parent = parent self.palette = palette self.values = values self.legend = parent self.label_items = [QGraphicsTextItem(text, self) for text in values] for i in self.label_items: i.setTextWidth(50) self.rect = QRectF() self.gradient_item = QGraphicsRectItem(self) self.gradient = QLinearGradient() self.gradient.setStops([(v * 0.1, self.palette[v * 0.1]) for v in range(11)]) self.orientation = Qt.Horizontal self.set_orientation(Qt.Vertical) def set_orientation(self, orientation): if self.orientation == orientation: return self.orientation = orientation if self.orientation == Qt.Vertical: height = max( [item.boundingRect().height() for item in self.label_items]) total_height = height * max(5, len(self.label_items)) interval = (total_height - self.label_items[-1].boundingRect().height()) / ( len(self.label_items) - 1) self.gradient_item.setRect(10, 0, self.gradient_width, total_height) self.gradient.setStart(10, 0) self.gradient.setFinalStop(10, total_height) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) y = 0 x = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) y += interval self.rect = QRectF( 10, 0, self.gradient_width + max([item.boundingRect().width() for item in self.label_items]), self.label_items[0].boundingRect().height() * max(5, len(self.label_items))) else: width = 50 height = max( [item.boundingRect().height() for item in self.label_items]) total_width = width * max(5, len(self.label_items)) interval = (total_width - self.label_items[-1].boundingRect().width()) / ( len(self.label_items) - 1) self.gradient_item.setRect(0, 0, total_width, self.gradient_width) self.gradient.setStart(0, 0) self.gradient.setFinalStop(total_width, 0) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) x = 0 y = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) x += interval self.rect = QRectF(0, 0, total_width, self.gradient_width + height) def boundingRect(self): return getattr(self, 'rect', QRectF()) def paint(self, painter, option, widget): pass
class OWLegendGradient(QGraphicsObject): gradient_width = 20 def __init__(self, palette, values, parent): QGraphicsObject.__init__(self, parent) self.parent = parent self.palette = palette self.values = values self.legend = parent self.label_items = [QGraphicsTextItem(text, self) for text in values] for i in self.label_items: i.setTextWidth(50) self.rect = QRectF() self.gradient_item = QGraphicsRectItem(self) self.gradient = QLinearGradient() self.gradient.setStops([(v*0.1, self.palette[v*0.1]) for v in range(11) ]) self.orientation = Qt.Horizontal self.set_orientation(Qt.Vertical) def set_orientation(self, orientation): if self.orientation == orientation: return self.orientation = orientation if self.orientation == Qt.Vertical: height = max([item.boundingRect().height() for item in self.label_items]) total_height = height * max(5, len(self.label_items)) interval = (total_height - self.label_items[-1].boundingRect().height()) / (len(self.label_items) -1) self.gradient_item.setRect(10, 0, self.gradient_width, total_height) self.gradient.setStart(10, 0) self.gradient.setFinalStop(10, total_height) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) y = 0 x = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) y += interval self.rect = QRectF(10, 0, self.gradient_width + max([item.boundingRect().width() for item in self.label_items]), self.label_items[0].boundingRect().height() * max(5, len(self.label_items))) else: width = 50 height = max([item.boundingRect().height() for item in self.label_items]) total_width = width * max(5, len(self.label_items)) interval = (total_width - self.label_items[-1].boundingRect().width()) / (len(self.label_items) -1) self.gradient_item.setRect(0, 0, total_width, self.gradient_width) self.gradient.setStart(0, 0) self.gradient.setFinalStop(total_width, 0) self.gradient_item.setBrush(QBrush(self.gradient)) self.gradient_item.setPen(QPen(Qt.NoPen)) x = 0 y = 30 for item in self.label_items: move_item_xy(item, x, y, self.parent.graph.animate_plot) x += interval self.rect = QRectF(0, 0, total_width, self.gradient_width + height) def boundingRect(self): return getattr(self, 'rect', QRectF()) def paint(self, painter, option, widget): pass