Ejemplo n.º 1
0
def colors(data, variable, palette=None):
    if palette is None:
        if is_discrete(variable):
            palette = colorpalette.ColorPaletteGenerator(len(variable.values))
        elif is_continuous(variable):
            palette = colorpalette.ColorPaletteBW()
            palette = colorpalette.ContinuousPaletteGenerator(
                QtGui.QColor(220, 220, 220), QtGui.QColor(0, 0, 0), False)
        else:
            raise TypeError()

    x = numpy.array(data[:, variable]).ravel()

    if is_discrete(variable):
        nvalues = len(variable.values)
        x[numpy.isnan(x)] = nvalues
        color_index = palette.getRGB(numpy.arange(nvalues + 1))
        # Unknown values as gray
        # TODO: This should already be a part of palette
        color_index[nvalues] = (128, 128, 128)
        colors = color_index[x.astype(int)]
    else:
        x, _ = scaled(x)
        mask = numpy.isnan(x)
        colors = numpy.empty((len(x), 3))
        colors[mask] = (128, 128, 128)
        colors[~mask] = [palette.getRGB(v) for v in x[~mask]]


#         colors[~mask] = interpolate(palette, x[~mask], left=Qt.gray)

    return colors
Ejemplo n.º 2
0
    def continuous_colors(data, palette=None):
        if palette is None:
            palette = colorpalette.ContinuousPaletteGenerator(
                QtGui.QColor(220, 220, 220),
                QtGui.QColor(0, 0, 0),
                False
            )
        amin, amax = numpy.nanmin(data), numpy.nanmax(data)
        span = amax - amin
        data = (data - amin) / (span or 1)

        mask = numpy.isnan(data)
        # Unknown values as gray
        # TODO: This should already be a part of palette
        colors = numpy.empty((len(data), 3))
        colors[mask] = (128, 128, 128)
        colors[~mask] = [palette.getRGB(v) for v in data[~mask]]
        return colors
Ejemplo n.º 3
0
class mdsplotutils(plotutils):
    NoFlags, Selected, Highlight = 0, 1, 2
    NoFill, Filled = 0, 1

    plotstyle = namespace(
        selected_pen=make_pen(Qt.yellow, width=3, cosmetic=True),
        highligh_pen=QtGui.QPen(Qt.blue, 1),
        selected_brush=None,
        default_color=QtGui.QColor(Qt.darkGray).rgba(),
        discrete_palette=colorpalette.ColorPaletteGenerator(),
        continuous_palette=colorpalette.ContinuousPaletteGenerator(
            QtGui.QColor(220, 220, 220),
            QtGui.QColor(0, 0, 0),
            False
        ),
        symbols=ScatterPlotItem.Symbols,
        point_size=10,
        min_point_size=5,
    )

    @staticmethod
    def column_data(table, var, mask=None):
        col, _ = table.get_column_view(var)
        dtype = float if var.is_primitive() else object
        col = numpy.asarray(col, dtype=dtype)
        if mask is not None:
            mask = numpy.asarray(mask, dtype=bool)
            return col[mask]
        else:
            return col

    @staticmethod
    def color_data(table, var=None, mask=None, plotstyle=None):
        N = len(table)
        if mask is not None:
            mask = numpy.asarray(mask, dtype=bool)
            N = numpy.count_nonzero(mask)

        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        if var is None:
            col = numpy.zeros(N, dtype=float)
            color_data = numpy.full(N, plotstyle.default_color, dtype=object)
        elif var.is_primitive():
            col = mdsplotutils.column_data(table, var, mask)
            if var.is_discrete:
                palette = plotstyle.discrete_palette
                if len(var.values) >= palette.number_of_colors:
                    palette = colorpalette.ColorPaletteGenerator(len(var.values))

                color_data = plotutils.discrete_colors(
                    col, nvalues=len(var.values), palette=palette)
            elif var.is_continuous:
                color_data = plotutils.continuous_colors(
                    col, palette=plotstyle.continuous_palette)
        else:
            raise TypeError("Discrete/Continuous variable or None expected.")

        return color_data

    @staticmethod
    def pen_data(basecolors, flags=None, plotstyle=None):
        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        pens = numpy.array(
            [mdsplotutils.make_pen(QtGui.QColor(*rgba), width=1)
             for rgba in basecolors],
            dtype=object)

        if flags is None:
            return pens

        selected_mask = flags & mdsplotutils.Selected
        if numpy.any(selected_mask):
            pens[selected_mask.astype(bool)] = plotstyle.selected_pen

        highlight_mask = flags & mdsplotutils.Highlight
        if numpy.any(highlight_mask):
            pens[highlight_mask.astype(bool)] = plotstyle.hightlight_pen

        return pens

    @staticmethod
    def brush_data(basecolors, flags=None, plotstyle=None):
        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        brush = numpy.array(
            [mdsplotutils.make_brush(QtGui.QColor(*c))
             for c in basecolors],
            dtype=object)

        if flags is None:
            return brush

        fill_mask = flags & mdsplotutils.Filled

        if not numpy.all(fill_mask):
            brush[~fill_mask] = QtGui.QBrush(Qt.NoBrush)
        return brush

    @staticmethod
    def shape_data(table, var, mask=None, plotstyle=None):
        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        N = len(table)
        if mask is not None:
            mask = numpy.asarray(mask, dtype=bool)
            N = numpy.nonzero(mask)

        if var is None:
            return numpy.full(N, "o", dtype=object)
        elif var.is_discrete:
            shape_data = mdsplotutils.column_data(table, var, mask)
            maxsymbols = len(plotstyle.symbols) - 1
            validmask = numpy.isfinite(shape_data)
            shape = shape_data % (maxsymbols - 1)
            shape[~validmask] = maxsymbols  # Special symbol for unknown values
            symbols = numpy.array(list(plotstyle.symbols))
            shape_data = symbols[numpy.asarray(shape, dtype=int)]

            if mask is None:
                return shape_data
            else:
                return shape_data[mask]
        else:
            raise TypeError()

    @staticmethod
    def size_data(table, var, mask=None, plotstyle=None):
        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        N = len(table)
        if mask is not None:
            mask = numpy.asarray(mask, dtype=bool)
            N = numpy.nonzero(mask)

        if var is None:
            return numpy.full(N, plotstyle.point_size, dtype=float)
        else:
            size_data = mdsplotutils.column_data(table, var, mask)
            size_data = mdsplotutils.normalized(size_data)
            size_mask = numpy.isnan(size_data)
            size_data = size_data * plotstyle.point_size + \
                        plotstyle.min_point_size
            size_data[size_mask] = plotstyle.min_point_size - 2

            if mask is None:
                return size_data
            else:
                return size_data[mask]

    @staticmethod
    def legend_data(color_var=None, shape_var=None, plotstyle=None):
        if plotstyle is None:
            plotstyle = mdsplotutils.plotstyle

        if color_var is not None and not color_var.is_discrete:
            color_var = None
        assert shape_var is None or shape_var.is_discrete
        if color_var is None and shape_var is None:
            return []

        if color_var is not None:
            palette = plotstyle.discrete_palette
            if len(color_var.values) >= palette.number_of_colors:
                palette = colorpalette.ColorPaletteGenerator(len(color_var.values))
        else:
            palette = None

        symbols = list(plotstyle.symbols)

        if shape_var is color_var:
            items = [(palette[i], symbols[i], name)
                     for i, name in enumerate(color_var.values)]
        else:
            colors = shapes = []
            if color_var is not None:
                colors = [(palette[i], "o", name)
                          for i, name in enumerate(color_var.values)]
            if shape_var is not None:
                shapes = [(QtGui.QColor(Qt.gray),
                           symbols[i % (len(symbols) - 1)], name)
                          for i, name in enumerate(shape_var.values)]
            items = colors + shapes

        return items

    @staticmethod
    def make_pen(color, width=1, cosmetic=True):
        pen = QtGui.QPen(color)
        pen.setWidthF(width)
        pen.setCosmetic(cosmetic)
        return pen

    @staticmethod
    def make_brush(color, ):
        return QtGui.QBrush(color, )
Ejemplo n.º 4
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.data = None
        self.subset_data = None
        self._subset_mask = None
        self._selection_mask = None
        self._item = None
        self.__selection_item = None
        self.__replot_requested = False

        box = gui.widgetBox(self.controlArea, "Axes")

        box1 = gui.widgetBox(box, "Displayed", margin=0)
        box1.setFlat(True)
        self.active_view = view = QListView(
            sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Ignored),
            selectionMode=QListView.ExtendedSelection,
            dragEnabled=True,
            defaultDropAction=Qt.MoveAction,
            dragDropOverwriteMode=False,
            dragDropMode=QListView.DragDrop,
            showDropIndicator=True,
            minimumHeight=50,
        )

        view.viewport().setAcceptDrops(True)
        movedown = QAction(
            "Move down", view,
            shortcut=QKeySequence(Qt.AltModifier | Qt.Key_Down),
            triggered=self.__deactivate_selection
        )
        view.addAction(movedown)

        self.varmodel_selected = model = DnDVariableListModel(
            parent=self)

        model.rowsInserted.connect(self._invalidate_plot)
        model.rowsRemoved.connect(self._invalidate_plot)
        model.rowsMoved.connect(self._invalidate_plot)

        view.setModel(model)

        box1.layout().addWidget(view)

        box1 = gui.widgetBox(box, "Other", margin=0)
        box1.setFlat(True)
        self.other_view = view = QListView(
            sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Ignored),
            selectionMode=QListView.ExtendedSelection,
            dragEnabled=True,
            defaultDropAction=Qt.MoveAction,
            dragDropOverwriteMode=False,
            dragDropMode=QListView.DragDrop,
            showDropIndicator=True,
            minimumHeight=50
        )
        view.viewport().setAcceptDrops(True)
        moveup = QtGui.QAction(
            "Move up", view,
            shortcut=QKeySequence(Qt.AltModifier | Qt.Key_Up),
            triggered=self.__activate_selection
        )
        view.addAction(moveup)

        self.varmodel_other = model = DnDVariableListModel(parent=self)
        view.setModel(model)

        box1.layout().addWidget(view)

        box = gui.widgetBox(self.controlArea, "Jittering")
        gui.comboBox(box, self, "jitter_value",
                     items=["None", "0.01%", "0.1%", "0.5%", "1%", "2%"],
                     callback=self._invalidate_plot)
        box.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        box = gui.widgetBox(self.controlArea, "Points")
        box.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)

        self.colorvar_model = itemmodels.VariableListModel(parent=self)
        self.shapevar_model = itemmodels.VariableListModel(parent=self)
        self.sizevar_model = itemmodels.VariableListModel(parent=self)
        self.labelvar_model = itemmodels.VariableListModel(parent=self)

        form = QtGui.QFormLayout(
            formAlignment=Qt.AlignLeft,
            labelAlignment=Qt.AlignLeft,
            fieldGrowthPolicy=QtGui.QFormLayout.AllNonFixedFieldsGrow,
            spacing=8
        )
        box.layout().addLayout(form)

        cb = gui.comboBox(box, self, "color_index",
                          callback=self._on_color_change)
        cb.setModel(self.colorvar_model)

        form.addRow("Colors", cb)
        alpha_slider = QSlider(
            Qt.Horizontal, minimum=10, maximum=255, pageStep=25,
            tickPosition=QSlider.TicksBelow, value=self.alpha_value)
        alpha_slider.valueChanged.connect(self._set_alpha)

        form.addRow("Opacity", alpha_slider)

        cb = gui.comboBox(box, self, "shape_index",
                          callback=self._on_shape_change)
        cb.setModel(self.shapevar_model)

        form.addRow("Shape", cb)

        cb = gui.comboBox(box, self, "size_index",
                          callback=self._on_size_change)
        cb.setModel(self.sizevar_model)

        form.addRow("Size", cb)
        size_slider = QSlider(
            Qt.Horizontal,  minimum=3, maximum=30, value=self.point_size,
            pageStep=3,
            tickPosition=QSlider.TicksBelow)

        size_slider.valueChanged.connect(self._set_size)
        form.addRow("", size_slider)

        toolbox = gui.widgetBox(self.controlArea, "Zoom/Select")
        toollayout = QtGui.QHBoxLayout()
        toolbox.layout().addLayout(toollayout)

        gui.auto_commit(self.controlArea, self, "auto_commit", "Commit")

        # Main area plot
        self.view = pg.GraphicsView(background="w")
        self.view.setRenderHint(QtGui.QPainter.Antialiasing, True)
        self.view.setFrameStyle(QtGui.QFrame.StyledPanel)
        self.viewbox = pg.ViewBox(enableMouse=True, enableMenu=False)
        self.viewbox.grabGesture(Qt.PinchGesture)
        self.view.setCentralItem(self.viewbox)

        self.mainArea.layout().addWidget(self.view)

        self.selection = PlotSelectionTool(
            self, selectionMode=PlotSelectionTool.Lasso)
        self.selection.setViewBox(self.viewbox)
        self.selection.selectionFinished.connect(self._selection_finish)

        self.zoomtool = PlotZoomTool(self)
        self.pantool = PlotPanTool(self)
        self.pinchtool = PlotPinchZoomTool(self)
        self.pinchtool.setViewBox(self.viewbox)

        self.continuous_palette = colorpalette.ContinuousPaletteGenerator(
            QtGui.QColor(220, 220, 220),
            QtGui.QColor(0, 0, 0),
            False
        )
        self.discrete_palette = colorpalette.ColorPaletteGenerator(13)

        def icon(name):
            path = "icons/Dlg_{}.png".format(name)
            path = pkg_resources.resource_filename(widget.__name__, path)
            return QtGui.QIcon(path)

        actions = namespace(
            zoomtofit=QAction(
                "Zoom to fit", self, icon=icon("zoom_reset"),
                shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_0),
                triggered=lambda:
                    self.viewbox.setRange(QRectF(-1.05, -1.05, 2.1, 2.1))),
            zoomin=QAction(
                "Zoom in", self,
                shortcut=QKeySequence(QKeySequence.ZoomIn),
                triggered=lambda: self.viewbox.scaleBy((1 / 1.25, 1 / 1.25))),
            zoomout=QAction(
                "Zoom out", self,
                shortcut=QKeySequence(QKeySequence.ZoomOut),
                triggered=lambda: self.viewbox.scaleBy((1.25, 1.25))),
            select=QAction(
                "Select", self, checkable=True, icon=icon("arrow"),
                shortcut=QKeySequence(Qt.ControlModifier + Qt.Key_1)),
            zoom=QAction(
                "Zoom", self, checkable=True, icon=icon("zoom"),
                shortcut=QKeySequence(Qt.ControlModifier + Qt.Key_2)),
            pan=QAction(
                "Pan", self, checkable=True, icon=icon("pan_hand"),
                shortcut=QKeySequence(Qt.ControlModifier + Qt.Key_3)),
        )
        self.addActions([actions.zoomtofit, actions.zoomin, actions.zoomout])

        group = QtGui.QActionGroup(self, exclusive=True)
        group.addAction(actions.select)
        group.addAction(actions.zoom)
        group.addAction(actions.pan)

        actions.select.setChecked(True)

        currenttool = self.selection

        def activated(action):
            nonlocal currenttool
            if action is actions.select:
                tool, cursor = self.selection, Qt.ArrowCursor
            elif action is actions.zoom:
                tool, cursor = self.zoomtool, Qt.ArrowCursor
            elif action is actions.pan:
                tool, cursor = self.pantool, Qt.OpenHandCursor
            else:
                assert False
            currenttool.setViewBox(None)
            tool.setViewBox(self.viewbox)
            self.viewbox.setCursor(QtGui.QCursor(cursor))
            currenttool = tool

        group.triggered[QAction].connect(activated)

        def button(action):
            b = QtGui.QToolButton()
            b.setDefaultAction(action)
            return b

        toollayout.addWidget(button(actions.select))
        toollayout.addWidget(button(actions.zoom))
        toollayout.addWidget(button(actions.pan))

        toollayout.addSpacing(4)
        toollayout.addWidget(button(actions.zoomtofit))
        toollayout.addStretch()
        toolbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)