示例#1
0
 def test_two_color(self):
     generator = GradientPaletteGenerator('#000', '#fff')
     np.testing.assert_equal(generator.getRGB(.5), (128, 128, 128))
     np.testing.assert_equal(generator.getRGB(np.nan), NAN_GREY)
     np.testing.assert_equal(generator.getRGB([0, .5, np.nan]),
                             [(0, 0, 0),
                              (128, 128, 128),
                              NAN_GREY])
示例#2
0
 def test_three_color(self):
     generator = GradientPaletteGenerator('#f00', '#000', '#fff')
     np.testing.assert_equal(generator.getRGB(.5), (0, 0, 0))
     np.testing.assert_equal(generator.getRGB(np.nan), NAN_GREY)
     np.testing.assert_equal(generator.getRGB([0, .5, 1]),
                             [(255, 0, 0),
                              (0, 0, 0),
                              (255, 255, 255)])
示例#3
0
 def test_three_color(self):
     generator = GradientPaletteGenerator('#f00', '#000', '#fff')
     for float_values, rgb in ((.5, (0, 0, 0)),
                               (np.nan, NAN_GREY),
                               ((0, .5, 1), ((255, 0, 0),
                                             (0, 0, 0),
                                             (255, 255, 255)))):
         np.testing.assert_equal(generator.getRGB(float_values), rgb)
示例#4
0
 def test_two_color(self):
     generator = GradientPaletteGenerator('#000', '#fff')
     for float_values, rgb in ((.5, (128, 128, 128)),
                               (np.nan, NAN_GREY),
                               ((0, .5, np.nan), ((0, 0, 0),
                                                  (128, 128, 128),
                                                  NAN_GREY))):
         np.testing.assert_equal(generator.getRGB(float_values), rgb)
 def test_three_color(self):
     generator = GradientPaletteGenerator("#f00", "#000", "#fff")
     for float_values, rgb in (
         (0.5, (0, 0, 0)),
         (np.nan, NAN_GREY),
         ((0, 0.5, 1), ((255, 0, 0), (0, 0, 0), (255, 255, 255))),
     ):
         np.testing.assert_equal(generator.getRGB(float_values), rgb)
 def test_two_color(self):
     generator = GradientPaletteGenerator("#000", "#fff")
     for float_values, rgb in (
         (0.5, (128, 128, 128)),
         (np.nan, NAN_GREY),
         ((0, 0.5, np.nan), ((0, 0, 0), (128, 128, 128), NAN_GREY)),
     ):
         np.testing.assert_equal(generator.getRGB(float_values), rgb)
    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);
                   ''')
def non_reentrant(func):
    """Prevent the function from reentry."""
    lock = Lock()

    @wraps(func)
    def locker(*args, **kwargs):
        if lock.acquire(False):
            try:
                return func(*args, **kwargs)
            finally:
                lock.release()

    return locker


CONTINUOUS_PALETTE = GradientPaletteGenerator('#00ffff', '#550066')


class SelectionMode:
    NONE,       \
    SEARCH,     \
    NEIGHBORS,  \
    AT_LEAST_N, \
    AT_MOST_N,  \
    ANY_NEIGH,  \
    AVG_NEIGH,  \
    MOST_CONN,  \
    FROM_INPUT  \
    = range(9)  # FML

示例#9
0
    def paintEvent(self, event):
        """Adapted from http://doc.qt.io/qt-5/qtwidgets-widgets-analogclock-example.html"""
        HOURHAND = QPolygon([QPoint(7, 8), QPoint(-7, 8), QPoint(0, -55)])
        MINUTEHAND = QPolygon([QPoint(7, 8), QPoint(-7, 8), QPoint(0, -87)])
        HOURCOLOR = QColor(Qt.black)
        MINUTECOLOR = QColor(0x11, 0x11, 0x11, 0xAA)

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(self.width() / 2, self.height() / 2)
        SIDE = 200
        side = min(self.width(), self.height())
        painter.scale(side / SIDE, side / SIDE)

        # Background (night/day)
        if self._time_to is not None:
            time = self._time_to.time()
            hour_offset = time.hour() + time.minute() / 60
            DAY, NIGHT = QColor(Qt.white), QColor('#5555ff')
            if 7 <= hour_offset <= 19:
                background = DAY
            elif 6 <= hour_offset <= 7:
                palette = GradientPaletteGenerator(NIGHT, DAY)
                background = palette[(hour_offset - 6) / (7 - 6)]
            elif 19 <= hour_offset <= 20:
                palette = GradientPaletteGenerator(DAY, NIGHT)
                background = palette[(hour_offset - 19) / (20 - 19)]
            else:
                assert hour_offset < 7 or hour_offset > 20
                background = NIGHT
            painter.setBrush(QBrush(background))
            painter.setPen(HOURCOLOR)
            painter.drawEllipse(-SIDE / 2, -SIDE / 2, SIDE, SIDE)

        # Minute tickmarks
        painter.save()
        painter.setPen(MINUTECOLOR)
        for j in range(60):
            painter.drawLine(94, 0, 97, 0)
            painter.rotate(6)
        painter.restore()

        # Hour tickmarks
        painter.save()
        painter.setPen(HOURCOLOR)
        for _ in range(12):
            painter.drawLine(88, 0, 98, 0)
            painter.rotate(30)
        painter.restore()

        # Hour span
        if self._time_from is not None:
            time_from = self._time_from.time()
            time_to = self._time_to.time()
            if time_from.secsTo(
                    time_to) / 3600 > .2:  # Don't draw really small intervals
                hour_from = (time_from.hour() +
                             time_from.minute() / 60) % 12 - 3
                hour_to = (time_to.hour() + time_to.minute() / 60) % 12 - 3
                startAngle = -hour_to * 30 * 16
                spanAngle = -hour_from * 30 * 16 - startAngle
                color = QColor(0xFF, 0xFF, 0, 0xAA)
                painter.save()
                painter.setBrush(QBrush(color, Qt.DiagCrossPattern))
                painter.setPen(color.darker(180))
                painter.drawPie(-SIDE / 2, -SIDE / 2, SIDE, SIDE, startAngle,
                                spanAngle)
                painter.restore()

        # Hour and minute hand
        if self._time_to is not None:
            time = self._time_to.time()

            painter.setPen(Qt.NoPen)

            painter.save()
            painter.setBrush(HOURCOLOR)
            painter.rotate(30 * (time.hour() + time.minute() / 60))
            painter.drawConvexPolygon(HOURHAND)
            painter.restore()

            painter.save()
            painter.setBrush(MINUTECOLOR)
            painter.rotate(6 * (time.minute() + time.second() / 60))
            painter.drawConvexPolygon(MINUTEHAND)
            painter.restore()
    def setSeries(self, timeseries, attr, xdim, ydim, fagg):
        if timeseries is None or not attr:
            self.clear()
            return
        # TODO: support discrete variables
        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)]

        xvals, xfunc = xdim.value
        yvals, yfunc = ydim.value

        values = Timeseries(Domain([], [], attr, source=timeseries.domain), timeseries).metas
        time_values = np.ravel(timeseries[:, timeseries.time_variable])

        if True:
            fromtimestamp = datetime.fromtimestamp
            time_values = [fromtimestamp(i) for i in time_values]

        if not yvals:
            yvals = sorted(set(yfunc(i) for i in time_values))
        if not xvals:
            xvals = sorted(set(xfunc(i) for i in time_values))

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

        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 = fagg(values[inds])
                    except ValueError:
                        aggval = np.nan
                else:
                    aggval = np.nan
                if np.isnan(aggval):
                    aggval = 'NaN'
                    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('#ccffcc', '#006600')
        for serie in series:
            for point in serie['data']:
                n = point['n']
                if isinstance(n, Number):
                    val = (n - minval) / ptpval
                    point['color'] = color[val]
                    point['states'] = dict(select=dict(color=selected_color[val]))

        # 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)])