Esempio n. 1
0
 def set_marker_color(self, attr, update=True):
     try:
         self._color_attr = variable = self.data.domain[attr]
         if len(self.data) == 0:
             raise Exception
     except Exception:
         self._color_attr = None
         self._legend_colors = []
     else:
         if variable.is_continuous:
             self._raw_color_values = values = self.data.get_column_view(variable)[0].astype(float)
             self._scaled_color_values = scale(values)
             self._colorgen = ContinuousPaletteGenerator(*variable.colors)
             min = np.nanmin(values)
             self._legend_colors = (['c',
                                     self._legend_values(variable, [min, np.nanmax(values)]),
                                     [color_to_hex(i) for i in variable.colors if i]]
                                    if not np.isnan(min) else [])
         elif variable.is_discrete:
             _values = np.asarray(self.data.domain[attr].values)
             __values = self.data.get_column_view(variable)[0].astype(np.uint16)
             self._raw_color_values = _values[__values]  # The joke's on you
             self._scaled_color_values = __values
             self._colorgen = ColorPaletteGenerator(len(variable.colors), variable.colors)
             self._legend_colors = ['d',
                                    self._legend_values(variable, range(len(_values))),
                                    list(_values),
                                    [color_to_hex(self._colorgen.getRGB(i))
                                     for i in range(len(_values))]]
     finally:
         if update:
             self.redraw_markers_overlay_image(new_image=True)
Esempio n. 2
0
 def set_marker_color(self, attr, update=True):
     try:
         self._color_attr = variable = self.data.domain[attr]
         if len(self.data) == 0:
             raise Exception
     except Exception:
         self._color_attr = None
         self._legend_colors = []
     else:
         if variable.is_continuous:
             self._raw_color_values = values = self.data.get_column_view(variable)[0].astype(float)
             self._scaled_color_values = scale(values)
             self._colorgen = ContinuousPaletteGenerator(*variable.colors)
             min = np.nanmin(values)
             self._legend_colors = (['c',
                                     self._legend_values(variable, [min, np.nanmax(values)]),
                                     [color_to_hex(i) for i in variable.colors if i]]
                                    if not np.isnan(min) else [])
         elif variable.is_discrete:
             _values = np.asarray(self.data.domain[attr].values)
             __values = self.data.get_column_view(variable)[0].astype(np.uint16)
             self._raw_color_values = _values[__values]  # The joke's on you
             self._scaled_color_values = __values
             self._colorgen = ColorPaletteGenerator(len(variable.colors), variable.colors)
             self._legend_colors = ['d',
                                    self._legend_values(variable, range(len(_values))),
                                    list(_values),
                                    [color_to_hex(self._colorgen.getRGB(i))
                                     for i in range(len(_values))]]
     finally:
         if update:
             self.redraw_markers_overlay_image(new_image=True)
Esempio n. 3
0
    def recompute_heatmap(self, points):
        if self.model is None or self.data is None:
            self.exposeObject('model_predictions', {})
            self.evalJS('draw_heatmap()')
            return

        latlons = np.array(points)
        table = Table(Domain([self.lat_attr, self.lon_attr]), latlons)
        try:
            predictions = self.model(table)
        except Exception as e:
            self._owwidget.Error.model_error(e)
            return
        else:
            self._owwidget.Error.model_error.clear()

        class_var = self.model.domain.class_var
        is_regression = class_var.is_continuous
        if is_regression:
            predictions = scale(np.round(predictions, 7))  # Avoid small errors
            kwargs = dict(
                extrema=self._legend_values(class_var, [np.nanmin(predictions),
                                                        np.nanmax(predictions)]))
        else:
            colorgen = ColorPaletteGenerator(len(class_var.values), class_var.colors)
            predictions = colorgen.getRGB(predictions)
            kwargs = dict(
                legend_labels=self._legend_values(class_var, range(len(class_var.values))),
                full_labels=list(class_var.values),
                colors=[color_to_hex(colorgen.getRGB(i))
                        for i in range(len(class_var.values))])
        self.exposeObject('model_predictions', dict(data=predictions, **kwargs))
        self.evalJS('draw_heatmap()')
Esempio n. 4
0
    def recompute_heatmap(self, points):
        if self.model is None or self.data is None:
            self.exposeObject('model_predictions', {})
            self.evalJS('draw_heatmap()')
            return

        latlons = np.array(points)
        table = Table(Domain([self.lat_attr, self.lon_attr]), latlons)
        try:
            predictions = self.model(table)
        except Exception as e:
            self._owwidget.Error.model_error(e)
            return
        else:
            self._owwidget.Error.model_error.clear()

        class_var = self.model.domain.class_var
        is_regression = class_var.is_continuous
        if is_regression:
            predictions = scale(np.round(predictions, 7))  # Avoid small errors
            kwargs = dict(
                extrema=self._legend_values(class_var, [np.nanmin(predictions),
                                                        np.nanmax(predictions)]))
        else:
            colorgen = ColorPaletteGenerator(len(class_var.values), class_var.colors)
            predictions = colorgen.getRGB(predictions)
            kwargs = dict(
                legend_labels=self._legend_values(class_var, range(len(class_var.values))),
                full_labels=list(class_var.values),
                colors=[color_to_hex(colorgen.getRGB(i))
                        for i in range(len(class_var.values))])
        self.exposeObject('model_predictions', dict(data=predictions, **kwargs))
        self.evalJS('draw_heatmap()')
Esempio n. 5
0
    def test_to_dict(self):
        desc = owcolor.DiscAttrDesc(self.var)
        self.assertEqual(desc.to_dict(), {})
        desc2, warns = owcolor.DiscAttrDesc.from_dict(self.var, desc.to_dict())
        self.assertEqual(warns, [])
        self.assertIsNone(desc2.new_name)
        self.assertIsNone(desc2.new_values)
        self.assertIsNone(desc2.new_colors)

        desc.name = "y"
        self.assertEqual(desc.to_dict(), {"rename": "y"})

        desc2, warns = owcolor.DiscAttrDesc.from_dict(self.var, desc.to_dict())
        self.assertEqual(warns, [])
        self.assertEqual(desc2.new_name, "y")
        self.assertIsNone(desc2.new_values)
        self.assertIsNone(desc2.new_colors)

        desc.set_value(1, "b2")
        desc.set_color(1, [1, 2, 3])
        desc.set_color(2, [2, 3, 4])
        self.assertEqual(
            desc.to_dict(), {
                "rename": "y",
                "renamed_values": {
                    "b": "b2"
                },
                "colors": {
                    "a": color_to_hex(desc.colors[0]),
                    "b": "#010203",
                    "c": "#020304"
                }
            })

        desc2, warns = owcolor.DiscAttrDesc.from_dict(self.var, desc.to_dict())
        self.assertEqual(warns, [])
        cols = list(desc.colors)
        cols[1:] = [[1, 2, 3], [2, 3, 4]]
        np.testing.assert_equal(desc2.colors, cols)
        self.assertEqual(desc2.values, ("a", "b2", "c"))

        desc2, warns = owcolor.DiscAttrDesc.from_dict(
            self.var,
            {
                "rename": "y",
                "renamed_values": {
                    "b": "b2",
                    "d": "x"
                },  # d is redundant
                "colors": {
                    "b": "#010203",
                    "c": "#020304",
                    "d": "#123456"
                }  # d is redundant and must be ignored
            })
        self.assertEqual(warns, [])
        cols = list(desc.colors)
        cols[1:] = [[1, 2, 3], [2, 3, 4]]
        np.testing.assert_equal(desc2.colors, cols)
        self.assertEqual(desc2.values, ("a", "b2", "c"))
Esempio n. 6
0
    def aggregate(self):
        if self.latlon is None or self.attr not in self.data.domain:
            self.clear(caches=False)
            return

        attr = self.data.domain[self.attr]

        if attr.is_discrete and self.agg_func not in self.AGG_FUNCS_DISCRETE:
            self.Error.aggregation_discrete(', '.join(map(str.lower, self.AGG_FUNCS_DISCRETE)))
            self.Warning.logarithmic_nonpositive.clear()
            self.clear(caches=False)
            return
        else:
            self.Error.aggregation_discrete.clear()

        try:
            regions, adm0, result, self.map.bounds = \
                self.get_grouped(self.lat_attr, self.lon_attr, self.admin, self.attr, self.agg_func)
        except ValueError:
            # This might happen if widget scheme File→Choropleth, and
            # some attr is selected in choropleth, and then the same attr
            # is set to string attr in File and dataset reloaded.
            # Our "dataflow" arch can suck my balls
            return

        # Only show discrete values that are contained in aggregated results
        discrete_values = []
        if attr.is_discrete and not self.agg_func.startswith('Count'):
            subset = sorted(result.drop_duplicates().dropna().astype(int))
            discrete_values = np.array(attr.values)[subset].tolist()
            discrete_colors = np.array(attr.colors)[subset].tolist()
            result.replace(subset, list(range(len(subset))), inplace=True)

        self.result_min_nonpositive = attr.is_continuous and result.min() <= 0
        force_quantization = self.color_quantization.startswith('log') and self.result_min_nonpositive
        self.Warning.logarithmic_nonpositive(shown=force_quantization)

        repr_time = isinstance(attr, TimeVariable) and self.agg_func not in self.AGG_FUNCS_CANT_TIME

        self.map.exposeObject(
            'results',
            dict(discrete=discrete_values,
                 colors=[color_to_hex(i)
                         for i in (discrete_colors if discrete_values else
                                   ((0, 0, 255), (255, 255, 0)) if attr.is_discrete else
                                   attr.colors[:-1])],  # ???
                 regions=list(adm0),
                 attr=attr.name,
                 have_nonpositive=self.result_min_nonpositive or bool(discrete_values),
                 values=result.to_dict(),
                 repr_vals=result.map(attr.repr_val).to_dict() if repr_time else {},
                 minmax=([result.min(), result.max()] if attr.is_discrete and not discrete_values else
                         [attr.repr_val(result.min()), attr.repr_val(result.max())] if repr_time or not discrete_values else
                         [])))

        self.map.evalJS('replot();')
Esempio n. 7
0
    def test_data(self):
        super().test_data()

        model = self.model

        self.assertIsNone(model.data(model.index(0, 4)))

        index = model.index(1, 2)
        self.assertEqual(model.data(index, Qt.DisplayRole), "e")
        self.assertEqual(model.data(index, Qt.EditRole), "e")
        font = model.data(index, Qt.FontRole)
        self.assertTrue(font is None or not font.bold())

        var_colors = self.descs[1].var.colors[1]
        color = model.data(index, Qt.DecorationRole)
        np.testing.assert_equal(color.getRgb()[:3], var_colors)

        color = model.data(index, owcolor.ColorRole)
        np.testing.assert_equal(color, var_colors)

        self.assertEqual(model.data(index, Qt.ToolTipRole),
                         color_to_hex(var_colors))

        self.assertIsNone(model.data(model.index(0, 4)))

        index = model.index(2, 5)
        self.assertEqual(model.data(index, Qt.DisplayRole), "k")
        self.assertEqual(model.data(index, Qt.EditRole), "k")
        font = model.data(index, Qt.FontRole)
        self.assertTrue(font is None or not font.bold())

        var_colors = self.descs[2].var.colors[4]
        color = model.data(index, Qt.DecorationRole)
        np.testing.assert_equal(color.getRgb()[:3], var_colors)

        color = model.data(index, owcolor.ColorRole)
        np.testing.assert_equal(color, var_colors)

        self.assertEqual(model.data(index, Qt.ToolTipRole),
                         color_to_hex(var_colors))

        self.descs[2].set_value(4, "foo")
        self.assertEqual(model.data(index, Qt.DisplayRole), "foo")
Esempio n. 8
0
 def to_dict(self):
     d = super().to_dict()
     if self.new_values is not None:
         d["renamed_values"] = \
             {k: v
              for k, v in zip(self.var.values, self.new_values)
              if k != v}
     if self.new_colors is not None:
         d["colors"] = {
             value: color_to_hex(color)
             for value, color in zip(self.var.values, self.colors)}
     return d
Esempio n. 9
0
 def _update_js_markers(self, visible, in_subset):
     self._visible = visible
     latlon = self._latlon_data
     self.exposeObject('latlon_data', dict(data=latlon[visible]))
     self.exposeObject(
         'jittering_offsets', self._jittering_offsets[visible]
         if self._jittering_offsets is not None else [])
     self.exposeObject(
         'selected_markers',
         dict(data=(self._selected_indices[visible] if self.
                    _selected_indices is not None else 0)))
     self.exposeObject('in_subset', in_subset.astype(np.int8))
     if not self._color_attr:
         self.exposeObject('color_attr', dict())
     else:
         colors = [
             color_to_hex(rgb) for rgb in self._colorgen.getRGB(
                 self._scaled_color_values[visible])
         ]
         self.exposeObject(
             'color_attr',
             dict(name=str(self._color_attr),
                  values=colors,
                  raw_values=self._raw_color_values[visible]))
     if not self._label_attr:
         self.exposeObject('label_attr', dict())
     else:
         self.exposeObject(
             'label_attr',
             dict(name=str(self._label_attr),
                  values=self._label_values[visible]))
     if not self._shape_attr:
         self.exposeObject('shape_attr', dict())
     else:
         self.exposeObject(
             'shape_attr',
             dict(name=str(self._shape_attr),
                  values=self._shape_values[visible],
                  raw_values=self._raw_shape_values[visible]))
     if not self._size_attr:
         self.exposeObject('size_attr', dict())
     else:
         self.exposeObject(
             'size_attr',
             dict(name=str(self._size_attr),
                  values=self._sizes[visible],
                  raw_values=self._raw_sizes[visible]))
     self.evalJS('''
         window.latlon_data = latlon_data.data;
         window.selected_markers = selected_markers.data;
         add_markers(latlon_data);
     ''')
Esempio n. 10
0
 def _update_js_markers(self, visible):
     self._visible = visible
     data = Table(Domain([self.lat_attr, self.lon_attr]), self.data)
     self.exposeObject('latlon_data', dict(data=data.X[visible]))
     self.exposeObject(
         'selected_markers',
         dict(data=(self._selected_indices[visible] if self.
                    _selected_indices is not None else 0)))
     if not self._color_attr:
         self.exposeObject('color_attr', dict())
     else:
         colors = [
             color_to_hex(rgb) for rgb in self._colorgen.getRGB(
                 self._scaled_color_values[visible])
         ]
         self.exposeObject(
             'color_attr',
             dict(name=str(self._color_attr),
                  values=colors,
                  raw_values=self._raw_color_values[visible]))
     if not self._label_attr:
         self.exposeObject('label_attr', dict())
     else:
         self.exposeObject(
             'label_attr',
             dict(name=str(self._label_attr),
                  values=self._label_values[visible]))
     if not self._shape_attr:
         self.exposeObject('shape_attr', dict())
     else:
         self.exposeObject(
             'shape_attr',
             dict(name=str(self._shape_attr),
                  values=self._shape_values[visible],
                  raw_values=self._raw_shape_values[visible]))
     if not self._size_attr:
         self.exposeObject('size_attr', dict())
     else:
         self.exposeObject(
             'size_attr',
             dict(name=str(self._size_attr),
                  values=self._sizes[visible],
                  raw_values=self._raw_sizes[visible]))
     self.evalJS('''
         window.latlon_data = latlon_data.data;
         window.selected_markers = selected_markers.data
         add_markers(latlon_data);
     ''')
Esempio n. 11
0
    def test_colors(self):
        var = DiscreteVariable.make("a", values=("F", "M"))
        self.assertIsNone(var._colors)
        self.assertEqual(var.colors.shape, (2, 3))
        self.assertFalse(var.colors.flags.writeable)

        var.colors = np.arange(6).reshape((2, 3))
        np.testing.assert_almost_equal(var.colors, [[0, 1, 2], [3, 4, 5]])
        self.assertEqual(var.attributes["colors"], {
            "F": "#000102",
            "M": "#030405"
        })
        self.assertFalse(var.colors.flags.writeable)
        with self.assertRaises(ValueError):
            var.colors[0] = [42, 41, 40]

        var = DiscreteVariable.make("x", values=("A", "B"))
        var.attributes["colors"] = {"A": "#0a0b0c", "B": "#0d0e0f"}
        np.testing.assert_almost_equal(var.colors,
                                       [[10, 11, 12], [13, 14, 15]])

        # Backward compatibility with list-like attributes
        var = DiscreteVariable.make("x", values=("A", "B"))
        var.attributes["colors"] = ["#0a0b0c", "#0d0e0f"]
        np.testing.assert_almost_equal(var.colors,
                                       [[10, 11, 12], [13, 14, 15]])

        # Test ncolors adapts to nvalues
        var = DiscreteVariable.make('foo', values=('d', 'r'))
        self.assertEqual(len(var.colors), 2)
        var.add_value('e')
        self.assertEqual(len(var.colors), 3)
        var.add_value('k')
        self.assertEqual(len(var.colors), 4)

        # Missing colors are retrieved from palette
        var = DiscreteVariable.make("x", values=("A", "B", "C"))
        palette = LimitedDiscretePalette(3).palette
        var.attributes["colors"] = {
            "C": color_to_hex(palette[0]),
            "B": "#0D0E0F"
        }
        np.testing.assert_almost_equal(var.colors,
                                       [palette[1], [13, 14, 15], palette[0]])

        # Variable with many values
        var = DiscreteVariable("x", values=tuple(f"v{i}" for i in range(1020)))
        self.assertEqual(len(var.colors), 1020)
Esempio n. 12
0
 def _update_js_markers(self, visible, in_subset):
     self._visible = visible
     latlon = np.c_[self.data.get_column_view(self.lat_attr)[0],
                    self.data.get_column_view(self.lon_attr)[0]]
     self.exposeObject('latlon_data', dict(data=latlon[visible]))
     self.exposeObject('jittering_offsets',
                       self._jittering_offsets[visible] if self._jittering_offsets is not None else [])
     self.exposeObject('selected_markers', dict(data=(self._selected_indices[visible]
                                                      if self._selected_indices is not None else 0)))
     self.exposeObject('in_subset', in_subset.astype(np.int8))
     if not self._color_attr:
         self.exposeObject('color_attr', dict())
     else:
         colors = [color_to_hex(rgb)
                   for rgb in self._colorgen.getRGB(self._scaled_color_values[visible])]
         self.exposeObject('color_attr',
                           dict(name=str(self._color_attr), values=colors,
                                raw_values=self._raw_color_values[visible]))
     if not self._label_attr:
         self.exposeObject('label_attr', dict())
     else:
         self.exposeObject('label_attr',
                           dict(name=str(self._label_attr),
                                values=self._label_values[visible]))
     if not self._shape_attr:
         self.exposeObject('shape_attr', dict())
     else:
         self.exposeObject('shape_attr',
                           dict(name=str(self._shape_attr),
                                values=self._shape_values[visible],
                                raw_values=self._raw_shape_values[visible]))
     if not self._size_attr:
         self.exposeObject('size_attr', dict())
     else:
         self.exposeObject('size_attr',
                           dict(name=str(self._size_attr),
                                values=self._sizes[visible],
                                raw_values=self._raw_sizes[visible]))
     self.evalJS('''
         window.latlon_data = latlon_data.data;
         window.selected_markers = selected_markers.data
         add_markers(latlon_data);
     ''')
Esempio n. 13
0
    def data(self, index, role=Qt.DisplayRole):
        # pylint: disable=too-many-return-statements
        row, col = index.row(), index.column()
        if col == 0:
            return super().data(index, role)

        desc = self.attrdescs[row]
        if col > len(desc.var.values):
            return None
        if role in (Qt.DisplayRole, Qt.EditRole):
            return desc.values[col - 1]

        color = desc.colors[col - 1]
        if role == Qt.DecorationRole:
            return QColor(*color)
        if role == Qt.ToolTipRole:
            return color_to_hex(color)
        if role == ColorRole:
            return color
        return None
Esempio n. 14
0
    def test_set_data(self):
        super().test_set_data()

        model = self.model
        emit = Mock()
        try:
            model.dataChanged.connect(emit)

            index = model.index(2, 5)

            self.assertEqual(model.data(index, Qt.DisplayRole), "k")
            self.assertEqual(model.data(index, Qt.EditRole), "k")
            self.assertFalse(model.setData(index, "foo", Qt.DisplayRole))
            emit.assert_not_called()
            self.assertEqual(model.data(index, Qt.DisplayRole), "k")
            self.assertTrue(model.setData(index, "foo", Qt.EditRole))
            emit.assert_called()
            emit.reset_mock()
            self.assertEqual(model.data(index, Qt.DisplayRole), "foo")
            self.assertEqual(self.descs[2].values, ("g", "h", "i", "j", "foo"))

            new_color = [0, 1, 2]
            self.assertTrue(model.setData(index, new_color + [255], ColorRole))
            emit.assert_called()
            emit.reset_mock()
            color = model.data(index, Qt.DecorationRole)
            rgb = [color.red(), color.green(), color.blue()]
            self.assertEqual(rgb, new_color)

            color = model.data(index, owcolor.ColorRole)
            self.assertEqual(list(color), new_color)

            self.assertEqual(model.data(index, Qt.ToolTipRole),
                             color_to_hex(new_color))

            np.testing.assert_equal(self.descs[2].colors[4], rgb)
        finally:
            model.dataChanged.disconnect(emit)
Esempio n. 15
0
 def set_color(self, i, color):
     self.colors = self.colors
     self._colors.flags.writeable = True
     self._colors[i, :] = color
     self._colors.flags.writeable = False
     self.attributes["colors"][i] = color_to_hex(color)
Esempio n. 16
0
 def colors(self, value):
     self._colors = value
     self._colors.flags.writeable = False
     self.attributes["colors"] = [color_to_hex(col) for col in value]
Esempio n. 17
0
 def colors(self, value):
     col1, col2, black = self._colors = value
     self.attributes["colors"] = \
         [color_to_hex(col1), color_to_hex(col2), black]
Esempio n. 18
0
    def setSeries(self, timeseries, attr, xdim, ydim, fagg):
        if timeseries is None or not attr:
            self.clear()
            return
        if isinstance(xdim, str) and xdim.isdigit():
            xdim = [str(i) for i in range(1, int(xdim) + 1)]
        if isinstance(ydim, str) and ydim.isdigit():
            ydim = [str(i) for i in range(1, int(ydim) + 1)]

        if isinstance(xdim, DiscreteVariable):
            xcol = timeseries.get_column_view(xdim)[0]
            xvals, xfunc = xdim.values, lambda i, _: xdim.repr_val(xcol[i])
        else:
            xvals, xfunc = xdim.value
        if isinstance(ydim, DiscreteVariable):
            ycol = timeseries.get_column_view(ydim)[0]
            yvals, yfunc = ydim.values, lambda i, _: ydim.repr_val(ycol[i])
        else:
            yvals, yfunc = ydim.value

        attr = attr[0]
        values = timeseries.get_column_view(attr)[0]
        time_values = [
            fromtimestamp(i, tz=timeseries.time_variable.timezone)
            for i in timeseries.time_values
        ]

        if not yvals:
            yvals = sorted(
                set(
                    yfunc(i, v) for i, v in enumerate(time_values)
                    if v is not None))
        if not xvals:
            xvals = sorted(
                set(
                    xfunc(i, v) for i, v in enumerate(time_values)
                    if v is not None))

        indices = defaultdict(list)
        for i, tval in enumerate(time_values):
            if tval is not None:
                indices[(xfunc(i, tval), yfunc(i, tval))].append(i)

        if self._owwidget.invert_date_order:
            yvals = yvals[::-1]

        series = []
        aggvals = []
        self.indices = []
        xname = self.AxesCategories.name_it(xdim)
        yname = self.AxesCategories.name_it(ydim)
        for yval in yvals:
            data = []
            series.append(dict(name=yname(yval), data=data))
            self.indices.append([])
            for xval in xvals:
                inds = indices.get((xval, yval), ())
                self.indices[-1].append(inds)
                point = dict(y=1)
                data.append(point)
                if inds:
                    try:
                        aggval = np.round(fagg(values[inds]), 4)
                    except ValueError:
                        aggval = np.nan
                else:
                    aggval = np.nan
                if isinstance(aggval, Number) and np.isnan(aggval):
                    aggval = 'N/A'
                    point['select'] = ''
                    point['color'] = 'white'
                else:
                    aggvals.append(aggval)
                point['n'] = aggval

        # TODO: allow scaling over just rows or cols instead of all values as currently
        try:
            maxval, minval = np.max(aggvals), np.min(aggvals)
        except ValueError:
            self.clear()
            return
        ptpval = maxval - minval
        color = GradientPaletteGenerator('#ffcccc', '#cc0000')
        selected_color = GradientPaletteGenerator('#cdd1ff', '#0715cd')
        for serie in series:
            for point in serie['data']:
                n = point['n']
                if isinstance(n, Number):
                    val = (n - minval) / ptpval

                    if attr.is_discrete:
                        point['n'] = attr.repr_val(n)
                    elif isinstance(attr, TimeVariable):
                        point['n'] = attr.repr_val(n)

                    if attr.is_discrete:
                        point['color'] = color = color_to_hex(
                            attr.colors[int(n)])
                        sel_color = QColor(color).darker(150).name()
                    else:
                        point['color'] = color[val]
                        sel_color = selected_color[val]
                    point['states'] = dict(
                        select=dict(borderColor="black", color=sel_color))

        # TODO: make a white hole in the middle. Center w/o data.
        self.chart(series=series,
                   xAxis_categories=[xname(i) for i in xvals],
                   yAxis_categories=[yname(i) for i in reversed(yvals)],
                   javascript_after='''
                       // Force zoomType which is by default disabled for polar charts
                       chart.options.chart.zoomType = 'xy';
                       chart.pointer.init(chart, chart.options);
                   ''')
Esempio n. 19
0
    def setSeries(self, timeseries, attr, xdim, ydim, fagg):
        if timeseries is None or not attr:
            self.clear()
            return
        if isinstance(xdim, str) and xdim.isdigit():
            xdim = [str(i) for i in range(1, int(xdim) + 1)]
        if isinstance(ydim, str) and ydim.isdigit():
            ydim = [str(i) for i in range(1, int(ydim) + 1)]

        if isinstance(xdim, DiscreteVariable):
            xcol = timeseries.get_column_view(xdim)[0]
            xvals, xfunc = xdim.values, lambda i, _: xdim.repr_val(xcol[i])
        else:
            xvals, xfunc = xdim.value
        if isinstance(ydim, DiscreteVariable):
            ycol = timeseries.get_column_view(ydim)[0]
            yvals, yfunc = ydim.values, lambda i, _: ydim.repr_val(ycol[i])
        else:
            yvals, yfunc = ydim.value

        attr = attr[0]
        values = timeseries.get_column_view(attr)[0]
        time_values = [fromtimestamp(i) for i in timeseries.time_values]

        if not yvals:
            yvals = sorted(set(yfunc(i, v) for i, v in enumerate(time_values) if v is not None))
        if not xvals:
            xvals = sorted(set(xfunc(i, v) for i, v in enumerate(time_values) if v is not None))

        indices = defaultdict(list)
        for i, tval in enumerate(time_values):
            if tval is not None:
                indices[(xfunc(i, tval), yfunc(i, tval))].append(i)

        if self._owwidget.invert_date_order:
            yvals = yvals[::-1]

        series = []
        aggvals = []
        self.indices = []
        xname = self.AxesCategories.name_it(xdim)
        yname = self.AxesCategories.name_it(ydim)
        for yval in yvals:
            data = []
            series.append(dict(name=yname(yval), data=data))
            self.indices.append([])
            for xval in xvals:
                inds = indices.get((xval, yval), ())
                self.indices[-1].append(inds)
                point = dict(y=1)
                data.append(point)
                if inds:
                    try:
                        aggval = np.round(fagg(values[inds]), 4)
                    except ValueError:
                        aggval = np.nan
                else:
                    aggval = np.nan
                if isinstance(aggval, Number) and np.isnan(aggval):
                    aggval = 'N/A'
                    point['select'] = ''
                    point['color'] = 'white'
                else:
                    aggvals.append(aggval)
                point['n'] = aggval

        # TODO: allow scaling over just rows or cols instead of all values as currently
        try:
            maxval, minval = np.max(aggvals), np.min(aggvals)
        except ValueError:
            self.clear()
            return
        ptpval = maxval - minval
        color = GradientPaletteGenerator('#ffcccc', '#cc0000')
        selected_color = GradientPaletteGenerator('#cdd1ff', '#0715cd')
        for serie in series:
            for point in serie['data']:
                n = point['n']
                if isinstance(n, Number):
                    val = (n - minval) / ptpval

                    if attr.is_discrete:
                        point['n'] = attr.repr_val(n)
                    elif isinstance(attr, TimeVariable):
                        point['n'] = attr.repr_val(n)

                    if attr.is_discrete:
                        point['color'] = color = color_to_hex(attr.colors[int(n)])
                        sel_color = QColor(color).darker(150).name()
                    else:
                        point['color'] = color[val]
                        sel_color = selected_color[val]
                    point['states'] = dict(select=dict(borderColor="black",
                                                       color=sel_color))

        # TODO: make a white hole in the middle. Center w/o data.
        self.chart(series=series,
                   xAxis_categories=[xname(i) for i in xvals],
                   yAxis_categories=[yname(i) for i in reversed(yvals)],
                   javascript_after='''
                       // Force zoomType which is by default disabled for polar charts
                       chart.options.chart.zoomType = 'xy';
                       chart.pointer.init(chart, chart.options);
                   ''')
    def update_plot(self):
        data = self.data
        if data is None or not len(data):
            self.clear()
            return

        self.optimize_button.setDisabled(not self.is_optimization_valid())

        self.Warning.too_many_selected_dimensions(
            len(self.selected_attrs),
            self.MAX_N_DIMS,
            shown=len(self.selected_attrs) > self.MAX_N_DIMS)
        selected_attrs = self.selected_attrs[:self.MAX_N_DIMS]

        sample = self.sample

        dimensions = []
        for attr in selected_attrs:
            attr = data.domain[attr]
            values = data.get_column_view(attr)[0][sample]
            dim = dict(label=attr.name,
                       values=values,
                       constraintrange=self.constraint_range.get(attr.name))
            if attr.is_discrete:
                dim.update(tickvals=np.arange(len(attr.values)),
                           ticktext=attr.values)
            elif isinstance(attr, TimeVariable):
                tickvals = [
                    np.nanmin(values),
                    np.nanmedian(values),
                    np.nanmax(values)
                ]
                ticktext = [attr.repr_val(i) for i in tickvals]
                dim.update(tickvals=tickvals, ticktext=ticktext)
            dimensions.append(dim)

        # Compute color legend
        line = dict()
        padding_right = 40
        if self.color_attr:
            attr = data.domain[self.color_attr]
            values = data.get_column_view(attr)[0][sample]
            line.update(color=values, showscale=True)
            title = '<br>'.join(
                textwrap.wrap(attr.name.strip(),
                              width=7,
                              max_lines=4,
                              placeholder='…'))
            if attr.is_discrete:
                padding_right = 90
                colors = [color_to_hex(i) for i in attr.colors]
                values_short = [
                    textwrap.fill(value, width=9, max_lines=1, placeholder='…')
                    for value in attr.values
                ]
                self.graph.exposeObject(
                    'discrete_colorbar',
                    dict(colors=colors,
                         title=title,
                         values=attr.values,
                         values_short=values_short))
                line.update(showscale=False,
                            colorscale=list(
                                zip(np.linspace(0, 1, len(attr.values)),
                                    colors)))
            else:
                padding_right = 0
                self.graph.exposeObject('discrete_colorbar', {})
                line.update(colorscale=list(
                    zip((0, 1), (color_to_hex(i) for i in attr.colors[:-1]))),
                            colorbar=dict(title=title))
                if isinstance(attr, TimeVariable):
                    tickvals = [
                        np.nanmin(values),
                        np.nanmedian(values),
                        np.nanmax(values)
                    ]
                    ticktext = [attr.repr_val(i) for i in tickvals]
                    line.update(colorbar=dict(title=title,
                                              tickangle=-90,
                                              tickvals=tickvals,
                                              ticktext=ticktext))
        self.graph.plot([Parcoords(line=line, dimensions=dimensions)],
                        padding_right=padding_right)
Esempio n. 21
0
 def set_color(self, i, color):
     self.colors = self.colors
     self._colors.flags.writeable = True
     self._colors[i, :] = color
     self._colors.flags.writeable = False
     self.attributes["colors"][i] = color_to_hex(color)
Esempio n. 22
0
 def colors(self, value):
     self._colors = value
     self._colors.flags.writeable = False
     self.attributes["colors"] = [color_to_hex(col) for col in value]
Esempio n. 23
0
 def colors(self, value):
     col1, col2, black = self._colors = value
     self.attributes["colors"] = \
         [color_to_hex(col1), color_to_hex(col2), black]