Exemple #1
0
 def test_rangexy_framewise_not_reset_if_triggering(self):
     stream = RangeXY(x_range=(0, 2), y_range=(0, 1))
     curve = DynamicMap(lambda z, x_range, y_range: Curve([1, 2, z]),
                        kdims=['z'],
                        streams=[stream]).redim.range(z=(0, 3))
     bokeh_server_renderer.get_plot(curve.opts(framewise=True))
     stream.event(x_range=(0, 3))
     self.assertEqual(stream.x_range, (0, 3))
Exemple #2
0
    def test_launch_server_with_stream(self):
        obj = Curve([])
        stream = RangeXY(source=obj)

        launched = []
        def modify_doc(doc):
            bokeh_renderer(obj, doc=doc)
            launched.append(True)
            server.stop()
        handler = FunctionHandler(modify_doc)
        app = Application(handler)
        server = Server({'/': app}, port=0)
        server.start()
        url = "http://localhost:" + str(server.port) + "/"
        pull_session(session_id='Test', url=url, io_loop=server.io_loop)

        self.assertTrue(len(launched)==1)
        cb = bokeh_renderer.last_plot.callbacks[0]
        self.assertIsInstance(cb, RangeXYCallback)
        self.assertEqual(cb.streams, [stream])
        x_range = bokeh_renderer.last_plot.handles['x_range']
        self.assertIn(cb.on_change, x_range._callbacks['start'])
        self.assertIn(cb.on_change, x_range._callbacks['end'])
        y_range = bokeh_renderer.last_plot.handles['y_range']
        self.assertIn(cb.on_change, y_range._callbacks['start'])
        self.assertIn(cb.on_change, y_range._callbacks['end'])
Exemple #3
0
 def test_rangexy_resolves(self):
     points = Points([1, 2, 3])
     RangeXY(source=points)
     plot = bokeh_server_renderer.get_plot(points)
     x_range = plot.handles['x_range']
     y_range = plot.handles['y_range']
     callback = plot.callbacks[0]
     x0_range_spec = callback.attributes['x0']
     x1_range_spec = callback.attributes['x1']
     y0_range_spec = callback.attributes['y0']
     y1_range_spec = callback.attributes['y1']
     resolved = callback.resolve_attr_spec(x0_range_spec,
                                           x_range,
                                           model=x_range)
     self.assertEqual(resolved, {'id': x_range.ref['id'], 'value': 0})
     resolved = callback.resolve_attr_spec(x1_range_spec,
                                           x_range,
                                           model=x_range)
     self.assertEqual(resolved, {'id': x_range.ref['id'], 'value': 2})
     resolved = callback.resolve_attr_spec(y0_range_spec,
                                           y_range,
                                           model=y_range)
     self.assertEqual(resolved, {'id': y_range.ref['id'], 'value': 1})
     resolved = callback.resolve_attr_spec(y1_range_spec,
                                           y_range,
                                           model=y_range)
     self.assertEqual(resolved, {'id': y_range.ref['id'], 'value': 3})
    def test_launch_server_with_complex_plot(self):
        dmap = DynamicMap(lambda x_range, y_range: Curve([]), streams=[RangeXY()])
        overlay = dmap * HLine(0)
        static = Polygons([]) * Path([]) * Curve([])
        layout = overlay + static

        _, server = self._launcher(layout)
        server.stop()
Exemple #5
0
 def test_rangexy_framewise_reset(self):
     stream = RangeXY(x_range=(0, 2), y_range=(0, 1))
     curve = DynamicMap(lambda z, x_range, y_range: Curve([1, 2, z]),
                        kdims=['z'],
                        streams=[stream]).redim.range(z=(0, 3))
     plot = bokeh_server_renderer.get_plot(curve.opts(framewise=True))
     plot.update((1, ))
     self.assertEqual(stream.y_range, None)
Exemple #6
0
    def test_rangexy_shared_axes(self):
        "Check that stream callbacks are shared on shared axes"
        c1 = Curve([1, 2, 3], 'x', 'y')
        c2 = Curve([1, 2, 3], 'x', 'y')
        stream1 = RangeXY(source=c1)
        stream2 = RangeXY(source=c2)
        layout = c1 + c2
        plot = bokeh_server_renderer.get_plot(layout)
        c1p, c2p = [p.subplots['main'] for p in plot.subplots.values()]
        c1_cb = c1p.callbacks[0]
        c2_cb = c2p.callbacks[0]

        assert set(c1_cb.streams) == {stream1, stream2}
        assert stream1 in c1_cb.handle_ids
        stream1_handles = c1_cb.handle_ids[stream1]
        assert stream1_handles['x_range'] == c1p.handles['x_range'].ref['id']
        assert stream1_handles['y_range'] == c1p.handles['y_range'].ref['id']
        stream2_handles = c1_cb.handle_ids[stream2]
        assert stream2_handles['x_range'] == c2p.handles['x_range'].ref['id']
        assert stream2_handles['y_range'] == c2p.handles['y_range'].ref['id']

        assert c2_cb.streams == []
Exemple #7
0
 def test_rangexy_datetime(self):
     curve = Curve(pd.util.testing.makeTimeDataFrame(), 'index', 'C')
     stream = RangeXY(source=curve)
     plot = bokeh_server_renderer.get_plot(curve)
     callback = plot.callbacks[0]
     callback.on_msg({
         "x0": curve.iloc[0, 0],
         'x1': curve.iloc[3, 0],
         "y0": 0.2,
         'y1': 0.8
     })
     self.assertEqual(stream.x_range[0], curve.iloc[0, 0])
     self.assertEqual(stream.x_range[1], curve.iloc[3, 0])
     self.assertEqual(stream.y_range, (0.2, 0.8))
Exemple #8
0
 def test_set_up_linked_change_stream_on_server_doc(self):
     obj = Curve([])
     stream = RangeXY(source=obj)
     server_doc = bokeh_renderer.server_doc(obj)
     self.assertEqual(len(bokeh_renderer.last_plot.callbacks), 1)
     cb = bokeh_renderer.last_plot.callbacks[0]
     self.assertIsInstance(cb, RangeXYCallback)
     self.assertEqual(cb.streams, [stream])
     x_range = bokeh_renderer.last_plot.handles['x_range']
     self.assertIn(cb.on_change, x_range._callbacks['start'])
     self.assertIn(cb.on_change, x_range._callbacks['end'])
     y_range = bokeh_renderer.last_plot.handles['y_range']
     self.assertIn(cb.on_change, y_range._callbacks['start'])
     self.assertIn(cb.on_change, y_range._callbacks['end'])
Exemple #9
0
    def test_launch_server_with_stream(self):
        obj = Curve([])
        stream = RangeXY(source=obj)

        _, server = self._launcher(obj)
        cb = bokeh_renderer.last_plot.callbacks[0]
        self.assertIsInstance(cb, RangeXYCallback)
        self.assertEqual(cb.streams, [stream])
        x_range = bokeh_renderer.last_plot.handles['x_range']
        self.assertIn(cb.on_change, x_range._callbacks['start'])
        self.assertIn(cb.on_change, x_range._callbacks['end'])
        y_range = bokeh_renderer.last_plot.handles['y_range']
        self.assertIn(cb.on_change, y_range._callbacks['start'])
        self.assertIn(cb.on_change, y_range._callbacks['end'])
        server.stop()
Exemple #10
0
    def test_launch_server_with_stream(self):
        el = Curve([])
        stream = RangeXY(source=el)

        obj, _ = bokeh_renderer._validate(el, None)
        server, _ = self._launcher(obj, port=6002)
        [(plot, _)] = obj._plots.values()

        cb = plot.callbacks[0]
        self.assertIsInstance(cb, RangeXYCallback)
        self.assertEqual(cb.streams, [stream])
        x_range = bokeh_renderer.last_plot.handles['x_range']
        self.assertIn(cb.on_change, x_range._callbacks['start'])
        self.assertIn(cb.on_change, x_range._callbacks['end'])
        y_range = bokeh_renderer.last_plot.handles['y_range']
        self.assertIn(cb.on_change, y_range._callbacks['start'])
        self.assertIn(cb.on_change, y_range._callbacks['end'])
        server.stop()
Exemple #11
0
    def test_launch_server_with_complex_plot(self):
        dmap = DynamicMap(lambda x_range, y_range: Curve([]), streams=[RangeXY()])
        overlay = dmap * HLine(0)
        static = Polygons([]) * Path([]) * Curve([])
        layout = overlay + static

        launched = []
        def modify_doc(doc):
            bokeh_renderer(layout, doc=doc)
            launched.append(True)
            server.stop()
        handler = FunctionHandler(modify_doc)
        app = Application(handler)
        server = Server({'/': app}, port=0)
        server.start()
        url = "http://localhost:" + str(server.port) + "/"
        pull_session(session_id='Test', url=url, io_loop=server.io_loop)
        self.assertTrue(len(launched)==1)
Exemple #12
0
    def __call__(self, dset, **params):
        self.p = ParamOverrides(self, params)

        if self.p.vdim is None:
            vdim = dset.vdims[0].name
        else:
            vdim = self.p.vdim

        ra_range = (ra0, ra1) = dset.range("ra")
        if self.p.ra_sampling:
            xsampling = (ra1 - ra0) / self.p.ra_sampling
        else:
            xsampling = None

        dec_range = (dec0, dec1) = dset.range("dec")
        if self.p.dec_sampling:
            ysampling = (dec1 - dec0) / self.p.dec_sampling
        else:
            ysampling = None

        if self.p.aggregator == "mean":
            aggregator = ds.mean(vdim)
        elif self.p.aggregator == "std":
            aggregator = ds.std(vdim)
        elif self.p.aggregator == "count":
            aggregator = ds.count()

        sky_range = RangeXY()
        if self.p.range_stream:

            def redim(dset, x_range, y_range):
                ranges = {}
                if x_range and all(isfinite(v) for v in x_range):
                    ranges["ra"] = x_range
                if y_range and all(isfinite(v) for v in x_range):
                    ranges["dec"] = y_range
                return dset.redim.range(**ranges) if ranges else dset

            dset = dset.apply(redim, streams=[self.p.range_stream])
            link_streams(self.p.range_stream, sky_range)
        streams = [sky_range, PlotSize()]

        pts = dset.apply(skypoints, streams=[self.p.filter_stream])

        reset = PlotReset(source=pts)
        reset.add_subscriber(partial(reset_stream, None,
                                     [self.p.range_stream]))

        rasterize_inst = rasterize.instance(aggregator=aggregator,
                                            streams=streams,
                                            x_sampling=xsampling,
                                            y_sampling=ysampling)
        raster_pts = apply_when(
            pts,
            operation=rasterize_inst,
            predicate=lambda pts: len(pts) > self.p.max_points)
        return raster_pts.opts(
            opts.Image(
                bgcolor="black",
                colorbar=True,
                cmap=self.p.cmap,
                min_height=100,
                responsive=True,
                tools=["hover"],
                symmetric=True,
            ),
            opts.Points(
                color=vdim,
                cmap=self.p.cmap,
                framewise=True,
                size=self.p.decimate_size,
                tools=["hover"],
                symmetric=True,
            ),
            opts.Overlay(hooks=[
                partial(reset_hook, x_range=ra_range, y_range=dec_range)
            ]),
        )
    def holoview_plot(self, ):
        """
        """
        import datashader as ds
        from holoviews.operation.datashader import aggregate, shade, datashade, dynspread
        from holoviews.streams import RangeXY

        self.ds_points = self.datashade(
            "Value" if len(self._data.data_dims) > 0 else None)
        self.ds_points = self.ds_points.opts(plot=dict(width=600, height=600))

        # Hover and zoom grid tool.
        self._hover_grid = hv.util.Dynamic(
            aggregate(self._points,
                      aggregator=ds.mean("Value"),
                      width=15,
                      height=15,
                      streams=[RangeXY(source=self.ds_points)]),
            operation=hv.QuadMesh).opts(plot=dict(tools=["hover"]),
                                        style=dict(alpha=0, hover_alpha=0.2))

        # Get the points in tapped rectangle
        self._posxy = DataShaderSelect(source=self._hover_grid,
                                       dataset=self._data.embedding)

        #self._posxy = hv.streams.Tap(source=self._hover_grid)

        def _dss_logger(**kwargs):
            import logging as log
            log.info("Handling event from datashader select: %s", str(kwargs))

        self._posxy.add_subscriber(_dss_logger)

        # Make layout
        self.tap_indicators = hv.DynamicMap(self.tap_points,
                                            kdims=[],
                                            streams=[self._posxy])
        self.selected_table = hv.DynamicMap(self.tap_table,
                                            streams=[self._posxy])

        self.tap_zoom = hv.DynamicMap(
            self.focus_plot, streams=[self._posxy],
            kdims=["Counts"]).opts(norm=dict(framewise=True)).redim.values(
                Counts=self._data.data_dims)

        def _h(Counts, index, fine_index, **kwargs):
            #print index, kwargs
            from holoviews.operation import histogram

            m = {
                Counts: "Value",
                "{}_frequency": "frequency",
            }
            if len(index) > 0:
                d = self._data.embedding.iloc[index]
                if len(fine_index) > 0:
                    d = d.iloc[fine_index]
                #print "Trying", Counts
                label = "{} {} points".format(Counts, len(d))
                r = histogram(
                    hv.Points(d),
                    #self.selected_table,
                    dimension=Counts,
                    dynamic=False).redim(**m)
            else:
                label = "{} {} points".format(Counts,
                                              len(self._data.embedding))
                #print "Alt", Counts
                r = histogram(self._points[Counts],
                              dimension="Value",
                              dynamic=False).redim(Value_frequency="frequency")

            #print(r)
            return r.relabel(label)

        from holoviews import streams
        self.zoom_selection = streams.Selection1D(source=self.tap_zoom)

        self.p = hv.DynamicMap(
            _h,
            kdims=["Counts"],
            streams=[
                self.zoom_selection.rename(index="fine_index"), self._posxy
            ]).redim.values(Counts=self._data.data_dims).opts(norm=dict(
                framewise=True))


        self._layout = self.ds_points * self._hover_grid * self.tap_indicators \
                       + self.selected_table + self.tap_zoom + self.p

        self._layout = self._layout.cols(2).opts(plot={"shared_axes": False})

        return self._layout
Exemple #14
0
            selected,
            kdims=[],
            vdims=['EventType', 'SUB', 'FEEDER_ID', 'XFMR', 'Phase'])

        return tab


# Map Tiles
map_tiles = tiles.opts(style=dict(alpha=1), plot=options)

# Create an explorer object and start visualizing data
explorer = SagSwellExplorer()
#pbk=parambokeh.Widgets(explorer,view_position='right', callback=explorer.event)

# Declare points selection
mv = hv.DynamicMap(explorer.make_view, streams=[explorer, RangeXY()])

# For Box Select
box = streams.BoundsXY(source=mv, bounds=(0, 0, 0, 0))
# For Table to display points selected with box select
dt = hv.DynamicMap(explorer.dec_tab, streams=[explorer, RangeXY(), box])

#plot = hv.renderer('bokeh').get_plot(mv*map_tiles+dt, doc=Document())

plot = hv.renderer('bokeh').instance(mode='server').get_plot(mv * map_tiles +
                                                             dt)
#plot = hv.renderer('bokeh').instance(mode='server').get_plot(mv*map_tiles)

parambokeh.Widgets(explorer,
                   view_position='right',
                   callback=explorer.event,
Exemple #15
0
            imag = min_y + y * pixel_size_y
            color = mandel(real, imag, iters)
            image[y, x] = color

    return image


def get_fractal(x_range, y_range):
    (x0, x1), (y0, y1) = x_range, y_range
    image = np.zeros((600, 600), dtype=np.uint8)
    return hv.Image(create_fractal(x0, x1, -y1, -y0, image, 200),
                    bounds=(x0, y0, x1, y1))


# Define stream linked to axis XY-range
range_stream = RangeXY(x_range=(-1., 1.), y_range=(-1., 1.))

# Create DynamicMap to compute fractal per zoom range and
# adjoin a logarithmic histogram
dmap = hv.DynamicMap(get_fractal,
                     label='Manderbrot Explorer',
                     streams=[range_stream]).hist(log=True)

# Define styling options
options = hv.Store.options('bokeh')
options.Image = {
    'style': Options(cmap='fire'),
    'plot': Options(logz=True, height=600, width=600, xaxis=None, yaxis=None)
}
options.Histogram = {
    'norm': Options(framewise=True),
Exemple #16
0
def create_doc(doc, data_dir):
    def get_spectrogram(s0=None,
                        s1=None,
                        size=1024,
                        overlap=1. / 8,
                        zfill=1,
                        mode='psd'):
        s_size = np.dtype(np.complex64).itemsize

        if s1 is None and s0 is None:
            ds = None
        elif s1 is None:
            ds = None
        elif s0 is None:
            ds = np.abs(s1)
        else:
            ds = np.abs(s1 - s0)

        if ds is not None and s0 is not None:
            flen = getsize(join(data_dir, file))
            print("file size: {} bytes".format(flen))
            if (ds + s0) * s_size > flen:
                ds = flen - s0 * s_size

        samples = np.memmap(join(data_dir, file),
                            dtype='complex64',
                            mode='r',
                            offset=s0 * s_size,
                            shape=(ds, ) if ds else None)

        if ds is None:
            ds = len(samples)

        if ds / size > (res + 0.5) * height:
            noverlap = -int(float(size) * float(ds) / size / height / res)
        else:
            noverlap = size // (1. / overlap)

        f, t, S = signal.spectrogram(samples,
                                     samp_rate,
                                     nperseg=size,
                                     nfft=int(
                                         next_power_of_2(size) * int(zfill)),
                                     noverlap=noverlap,
                                     return_onesided=False,
                                     scaling='density',
                                     mode=mode)  #

        f = fftshift(f)
        S = fftshift(S, axes=(0, ))

        if mode == 'psd':
            S = 10 * np.log10(S)

        return f, t, S, samples

    def get_spectrogram_img(z_min, z_max, tf_r, zfill, overlap, show_realfreq,
                            freq_unit, x_range, y_range):
        lock.acquire()

        show_realfreq = bool(show_realfreq)

        hv_image = None
        try:
            print("y_range:", y_range, type(y_range))

            if type(y_range[0]) != float:
                if np.issubdtype(y_range[0],
                                 np.datetime64) and time is not None:
                    y_range = [
                        (y - np.datetime64(time)
                         ).astype('timedelta64[us]').astype('float') / 1e6
                        for y in y_range
                    ]
                #elif np.issubdtype(y0, np.timedelta64):
                #    y0, y1 = [y.astype('timedelta64[s]').astype('float') for y in [y0,y1]]

            # tranform back to relative frequency if required

            print(doc.session_context.show_realfreq, x_range)

            last_freq_unit = doc.session_context.freq_unit
            x_range = [x * freq_units_names[last_freq_unit] for x in x_range]

            if doc.session_context.show_realfreq:
                x_range = [(x - freq) for x in x_range]

            print(doc.session_context.show_realfreq, "after transform",
                  x_range)

            (x0, x1), (y0, y1) = x_range, y_range

            #print("y0 dtype:", y0.dtype)

            s0, s1 = sorted([
                min(max(int(yr * samp_rate), 0), total_samples)
                for yr in [y0, y1]
            ])

            scale = samp_rate / np.abs(x_range[1] - x_range[0])

            size = int(width *
                       scale)  # required freq resolution to fulfill zoom level

            ds = np.abs(
                s1 - s0)  # number of samples covered at the current zoom level
            if ds / size < height:
                size = int(np.sqrt(ds * scale * 10**tf_r))

            f, t, S, samples = get_spectrogram(
                s0,
                s1,
                size=size,
                overlap=overlap,
                mode=mode,
                zfill=zfill if size < res * width else 1)
            t += max(min(y0, y1), 0)

            f_range = (x0 <= f) & (f <= x1)
            image = S[f_range, :]
            f = f[f_range]

            #if ds / size > height:
            #    image = signal.resample(image, height*2, axis=0)

            print(image.shape)

            if intp_enabled:
                ratio = np.array(image.shape, dtype=np.float) / np.array(
                    (height * res, width * res))
                if np.min(ratio) < 1:
                    scale = np.max(
                        np.abs(image)
                    )  # normalization factor for image because rescale needs that
                    image = rescale(image / scale, 1. / np.min(ratio),
                                    order=1) * scale

                    f = signal.resample(f, image.shape[0])
                    t = signal.resample(t, image.shape[1])

                    print("after resampling: ", image.shape)

            del samples
            #image = hv.Image(image, bounds=(x0, y0, x1, y1)).redim.range(z=(z_min, z_max)) # TODO get exact values in bounds

            if show_realtime and time is not None:
                t = np.datetime64(time) + np.array(
                    t * 1e6).astype('timedelta64[us]')
            #else:
            #    t = (t*1e6) #.astype('timedelta64[us]')

            if show_realfreq:
                f += freq
            f /= freq_units_names[freq_unit]

            #image = image.astype('float16') # trying to reduce network bandwidth...

            print("image dtype:", image.dtype)

            #hv_image = hv.Image(np.flip(image, axis=1), bounds=(min(f), max(t), max(f), min(t))) \
            hv_image = hv.Image(xr.DataArray(image, coords=[f,t], dims=['f','t'], name='z'), ['f','t'], 'z') \
                .options(
                    xlabel="Frequency [{}]".format(freq_unit),
                    ylabel="Time " + '[s]' if not show_realtime else '') \
                .redim.range(z=(z_min, z_max))

            if doc.session_context.show_realfreq != show_realfreq or doc.session_context.freq_unit != freq_unit:
                hv_image = hv_image \
                    .redim.range(f=(min(f), max(f))) \
                    .redim.range(t=(min(t), max(t)))
                print("redimming axis range")

            doc.session_context.show_realfreq = show_realfreq
            doc.session_context.freq_unit = freq_unit

        except Exception as e:
            print("Exception in image generation:", e)
            print(traceback.format_exc())

        lock.release()
        return hv_image

    def get_param(name, default, t=str):
        try:
            args = doc.session_context.request.arguments
            if t == str:
                p = str(args.get(name)[0], 'utf-8')
            else:
                p = t(args.get(name)[0])
        except:
            p = default
        return p

    time = None
    freq = 0

    file = basename(get_param('file', '', str))
    skip = get_param('skip', 0, int)
    keep = get_param('keep', None, int)

    # low resolution for raspberry
    width, height = get_param('width', 600, int), get_param('height', 500, int)
    res = get_param('res', 1.5, float)
    ds_enabled = get_param('ds', None, str)  # datashade option (default: avg)
    intp_enabled = get_param('intp', 0, int)  # interpolation enable flap
    show_realtime = bool(get_param('rt', 0,
                                   int))  # show real time on vertical axis

    mode = get_param('mode', 'psd', str)

    t_range = get_param('t', None, str)
    f_range = get_param('f', None, str)

    if t_range is not None:
        try:
            parts = t_range.split(",")
            if len(parts) == 2:
                t_range = list(map(float, parts))
        except:
            pass

    if f_range is not None:
        try:
            parts = f_range.split(",")
            if len(parts) == 2:
                f_range = list(map(float, parts))
            elif len(parts) == 1:
                _f = abs(float(parts[0]))
                f_range = (-_f, _f)
        except:
            pass

    if file.endswith(".meta"):
        config = ConfigParser()
        config.read(join(data_dir, file))

        file = splitext(file)[0] + ".raw"
        samp_rate = int(config['main']['samp_rate'])
        freq = float(config['main']['freq'])
        time = datetime.fromtimestamp(float(config['main']['time']))
    else:
        samp_rate = get_param('samp_rate', 128000, int)

    f, t, S, samples = get_spectrogram(s0=skip * samp_rate,
                                       s1=keep * samp_rate if keep else None,
                                       size=width,
                                       mode=mode)
    total_samples = len(samples)

    del samples

    # default is True
    if show_realtime and time is not None:
        t = np.datetime64(time) + np.array(t).astype('timedelta64[s]')

    doc.session_context.show_realfreq = False
    doc.session_context.freq_unit = freq_units[1000]

    range_stream = RangeXY(x_range=tuple(
        x / freq_units_names[doc.session_context.freq_unit]
        for x in ((min(f_range), max(f_range)) if f_range else (min(f),
                                                                max(f)))),
                           y_range=(max(t_range), min(t_range)) if t_range else
                           (max(t), min(t)))  # transient=True

    z_range = (np.min(S), np.max(S))
    z_init = np.percentile(S, (50, 100))

    dmap = hv.DynamicMap(
        get_spectrogram_img,
        streams=[range_stream],
        kdims=[
            hv.Dimension('z_min', range=z_range, default=z_init[0]),
            hv.Dimension('z_max', range=z_range, default=z_init[1]),
            hv.Dimension('tf_r',
                         label='Time-Frequency pixel ratio',
                         range=(-10., 10.),
                         default=0.),
            hv.Dimension('zfill',
                         label='Zero-filling factor',
                         range=(1, 10),
                         default=2),
            hv.Dimension('overlap',
                         label='Overlap factor',
                         range=(-1., 1.),
                         default=1. / 8),
            #hv.Dimension('show_realtime', label='Show real time on vertical axis', range=(0,1), default=0),
            hv.Dimension('show_realfreq',
                         label='Show real frequency',
                         range=(0, 1),
                         default=int(doc.session_context.show_realfreq)),
            hv.Dimension('freq_unit',
                         label='Frequency unit',
                         values=list(
                             map(lambda x: freq_units[x],
                                 sorted(freq_units.keys()))),
                         default=doc.session_context.freq_unit),
            #hv.Dimension('mode', label='Spectrogram mode', values=['psd', 'angle', 'phase', 'magnitude'], default='psd')
        ]).options(
            framewise=True,  # ???
        )  #.redim.range(z=z_init)
    #dmap = dmap.opts(opts.Image(height=height, width=width))

    if ds_enabled != None:
        print("datashade enabled: yes")
        if ds_enabled == "" or ds_enabled == "mean":
            ds_enabled = dsr.mean
        elif ds_enabled == "max":
            ds_enabled = dsr.max
        else:
            print(
                "warning: invalid option for datashade. using default value: mean"
            )
            ds_enabled = dsr.mean
        dmap = regrid(dmap,
                      aggregator=ds_enabled,
                      interpolation='linear',
                      upsample=True,
                      height=height * 2,
                      width=width * 2)  # aggregation=dsr.max

    #dmap = dmap.hist(num_bins=150, normed=False)

    dmap = dmap.opts(
        opts.Image(
            cmap='viridis',
            framewise=True,
            colorbar=True,
            height=height,
            width=width,
            tools=['hover'],
            title='{}, {} {} sps'.format(
                time.strftime('%Y-%m-%d %H:%M:%S') if time else 'Time unknown',
                format_freq(freq), samp_rate)),
        opts.Histogram(framewise=False, width=150))

    #plot = renderer.get_plot(hist, doc).state
    #widget = renderer.get_widget(hist, None, position='right').state

    #hvobj = layout([plot, widget])

    #plot = layout([renderer.get_plot(hist, doc).state])
    #doc.add_root(plot)

    doc = renderer.server_doc(dmap, doc=doc)
    doc.title = 'Waterfall Viewer'
Exemple #17
0
             yaxis=None,
             bgcolor='black',
             show_grid=False)
opts2 = dict(width=1000, height=600, x_sampling=1, y_sampling=1, dynamic=False)


class OSMExplorer(hv.streams.Stream):
    alpha = param.Magnitude(default=0.75, doc="Map opacity")
    colormap = param.ObjectSelector(default=cm_n["fire"],
                                    objects=cm_n.values())

    def make_view(self, x_range, y_range, **kwargs):
        tiles = map_tiles.options(alpha=self.alpha, **opts1)
        points = hv.Points(df, ['x', 'y'])
        return tiles * datashade(points,
                                 cmap=self.colormap,
                                 x_range=x_range,
                                 y_range=y_range,
                                 **opts2)


explorer = OSMExplorer(name="Open Street Map GPS")
dmap = hv.DynamicMap(explorer.make_view, streams=[explorer, RangeXY()])

plot = hv.renderer('bokeh').instance(mode='server').get_plot(dmap)
parambokeh.Widgets(explorer,
                   view_position='right',
                   callback=explorer.event,
                   plots=[plot.state],
                   mode='server')
Exemple #18
0
    output = parambokeh.view.Plot()

    def make_view(self, x_range, y_range, alpha, colormap, plot, passengers,
                  **kwargs):
        map_tiles = tiles(style=dict(alpha=alpha), plot=tile_options)
        points = hv.Points(df,
                           kdims=[plot + '_x', plot + '_y'],
                           vdims=['passenger_count'])
        if passengers != passenger_counts:
            points = points.select(passenger_count=passengers)
        taxi_trips = datashade(points,
                               x_sampling=1,
                               y_sampling=1,
                               cmap=colormap,
                               dynamic=False,
                               x_range=x_range,
                               y_range=y_range)
        return map_tiles * taxi_trips


selector = NYCTaxiExplorer(name="NYC Taxi Trips")
selector.output = hv.DynamicMap(selector.make_view,
                                streams=[selector,
                                         RangeXY(),
                                         PlotSize()])

doc = parambokeh.Widgets(selector,
                         view_position='right',
                         callback=selector.event,
                         mode='server')
Exemple #19
0
    def test_interactive_streams(self):
        ys = np.arange(10)
        scatter1 = hv.Scatter(ys)
        scatter2 = hv.Scatter(ys)
        scatter3 = hv.Scatter(ys)

        # Single stream on the first scatter
        rangexy1 = RangeXY(source=scatter1)

        # Multiple streams of the same type on second scatter
        boundsxy2a = BoundsXY(source=scatter2)
        boundsxy2b = BoundsXY(source=scatter2)

        # Multiple streams of different types on third scatter
        rangexy3 = RangeXY(source=scatter3)
        boundsxy3 = BoundsXY(source=scatter3)
        selection1d3 = Selection1D(source=scatter3)

        # Build layout and layout Pane
        layout = scatter1 + scatter2 + scatter3
        layout_pane = pn.pane.HoloViews(layout, backend='plotly')

        # Get plotly pane reference
        doc = Document()
        comm = Comm()
        layout_pane.get_root(doc, comm)
        _, plotly_pane = next(iter(layout_pane._plots.values()))

        # Simulate zoom and check that RangeXY streams updated accordingly
        plotly_pane.viewport = {
            'xaxis.range': [1, 3],
            'yaxis.range': [2, 4],
            'xaxis2.range': [3, 5],
            'yaxis2.range': [4, 6],
            'xaxis3.range': [5, 7],
            'yaxis3.range': [6, 8],
        }

        self.assertEqual(rangexy1.x_range, (1, 3))
        self.assertEqual(rangexy1.y_range, (2, 4))
        self.assertEqual(rangexy3.x_range, (5, 7))
        self.assertEqual(rangexy3.y_range, (6, 8))

        plotly_pane.viewport = None
        self.assertIsNone(rangexy1.x_range)
        self.assertIsNone(rangexy1.y_range)
        self.assertIsNone(rangexy3.x_range)
        self.assertIsNone(rangexy3.y_range)

        # Simulate box selection and check that BoundsXY and Selection1D streams
        # update accordingly

        # Box select on second subplot
        plotly_pane.selected_data = {
            'points': [],
            'range': {
                'x2': [10, 20],
                'y2': [11, 22]
            }
        }

        self.assertEqual(boundsxy2a.bounds, (10, 11, 20, 22))
        self.assertEqual(boundsxy2b.bounds, (10, 11, 20, 22))

        # Box selecrt on third subplot
        plotly_pane.selected_data = {
            'points': [
                {'curveNumber': 2, 'pointNumber': 0},
                {'curveNumber': 2, 'pointNumber': 3},
                {'curveNumber': 2, 'pointNumber': 7},
            ],
            'range': {
                'x3': [0, 5],
                'y3': [1, 6]
            }
        }

        self.assertEqual(boundsxy3.bounds, (0, 1, 5, 6))
        self.assertEqual(selection1d3.index, [0, 3, 7])

        # bounds streams on scatter 2 are None
        self.assertIsNone(boundsxy2a.bounds)
        self.assertIsNone(boundsxy2b.bounds)

        # Clear selection
        plotly_pane.selected_data = None
        self.assertIsNone(boundsxy3.bounds)
        self.assertIsNone(boundsxy2a.bounds)
        self.assertIsNone(boundsxy2b.bounds)
        self.assertEqual(selection1d3.index, [])
Exemple #20
0
        size=4,
    )
    return points * tile


# Layout and connect

template = pn.template.FastListTemplate(title="Load Forecasting - ERCOT", theme="dark")
if "dark" in str(template.theme).lower():
    tile = gvts.CartoMidnight
else:
    tile = gvts.CartoLight

plot = get_station_map(STATIONLIST, tile=tile)

stream = RangeXY(source=plot)
dataframe_label = pn.pane.Markdown()
dataframe_widget = pn.widgets.DataFrame()


@param.depends(
    x=stream.param.x_range, y=stream.param.y_range, top=settings.param.top_stations, watch=True
)
def update_bounds(x=None, y=None, top=None):
    if x and y:
        x_query = (STATIONLIST["X"] >= x[0]) & (STATIONLIST["X"] <= x[1])
        y_query = (STATIONLIST["Y"] >= y[0]) & (STATIONLIST["Y"] <= y[1])
        data = STATIONLIST[x_query & y_query]
    else:
        data = STATIONLIST
    if not top:
Exemple #21
0
    def __init__(self, store, **param):

        super().__init__(**param)

        self.store = store
        self.overview = create_overview(self.on_overview_selected_tracts_updated, active_tracts=[])

        self._clear_metrics_button = pn.widgets.Button(name="Clear", width=30, align="end")
        self._clear_metrics_button.on_click(self._on_clear_metrics)

        self._submit_repository = pn.widgets.Button(name="Load Data", width=50, align="end")
        self._submit_repository.on_click(self._on_load_data_repository)

        self._submit_comparison = pn.widgets.Button(name="Submit", width=50, align="end")
        self._submit_comparison.on_click(self._update)

        self.flag_filter_select = pn.widgets.Select(
            name="Add Flag Filter", width=160, options=self.store.active_dataset.flags
        )

        self.flag_state_select = pn.widgets.Select(name="Flag State", width=75, options=["True", "False"])

        self.flag_submit = pn.widgets.Button(name="Add Flag Filter", width=10, height=30, align="end")
        self.flag_submit.on_click(self.on_flag_submit_click)

        self.flag_filter_selected = pn.widgets.Select(name="Active Flag Filters", width=250)

        self.flag_remove = pn.widgets.Button(name="Remove Flag Filter", width=50, height=30, align="end")
        self.flag_remove.on_click(self.on_flag_remove_click)

        self.query_filter_submit = pn.widgets.Button(name="Run Query Filter", width=100, align="end")
        self.query_filter_submit.on_click(self.on_run_query_filter_click)

        self.query_filter_clear = pn.widgets.Button(name="Clear", width=50, align="end")
        self.query_filter_clear.on_click(self.on_query_filter_clear)

        self.new_column_submit = pn.widgets.Button(name="Define New Column", width=100, align="end")
        self.new_column_submit.on_click(self.on_define_new_column_click)

        self.status_message = pn.pane.HTML(sizing_mode="stretch_width", max_height=10)
        self.adhoc_js = pn.pane.HTML(sizing_mode="stretch_width", max_height=10)
        self._info = pn.pane.HTML(sizing_mode="stretch_width", max_height=10)
        self._flags = pn.pane.HTML(sizing_mode="stretch_width", max_height=10)
        self._metric_panels = []
        self._metric_layout = pn.Column()
        self._switch_view = self._create_switch_view_buttons()
        self._switch_stack = self._create_switch_datastack_buttons()
        self._plot_top = pn.Row(sizing_mode="stretch_width", margin=(10, 10, 10, 10))

        self._plot_layout = pn.Column(sizing_mode="stretch_width", margin=(10, 10, 10, 10))

        self._skyplot_tabs = pn.Tabs(sizing_mode="stretch_both")
        self.skyplot_layout = pn.Column(sizing_mode="stretch_width", margin=(10, 10, 10, 10))

        self._detail_tabs = pn.Tabs(sizing_mode="stretch_both")
        self.list_layout = pn.Column(sizing_mode="stretch_width")
        self.detail_plots_layout = pn.Column(sizing_mode="stretch_width")

        self._coadd_toggles = {}
        self._filter_streams = {}
        self._skyplot_range_stream = RangeXY()
        self._scatter_range_stream = RangeXY()

        self._visits_selections = {}

        self._update(None)
    def test_rangexy_dynamic_map(self):

        # Create dynamic map that inputs rangexy, returns scatter on bounds
        scatter = Scatter([[0, 1], [0, 1]], kdims=["x"], vdims=["y"])
        rangexy = RangeXY(source=scatter)

        def dmap_fn(x_range, y_range):
            x_range = (0, 1) if x_range is None else x_range
            y_range = (0, 1) if y_range is None else y_range
            return Scatter(
                [[x_range[0], y_range[0]], [x_range[1], y_range[1]]],
                kdims=["x1"],
                vdims=["y1"])

        dmap = DynamicMap(dmap_fn, streams=[rangexy])

        # Convert to Dash
        components = to_dash(self.app, [scatter, dmap], reset_button=True)

        # Check returned components
        self.assertIsInstance(components, DashComponents)
        self.assertEqual(len(components.graphs), 2)
        self.assertEqual(len(components.kdims), 0)
        self.assertIsInstance(components.store, Store)
        self.assertEqual(len(components.resets), 1)

        # Get arguments passed to @app.callback decorator
        decorator_args = list(self.app.callback.call_args_list[0])[0]
        outputs, inputs, states = decorator_args

        # Check outputs
        expected_outputs = [(g.id, "figure") for g in components.graphs] + \
                           [(components.store.id, "data")]
        self.assertEqual([(output.component_id, output.component_property)
                          for output in outputs], expected_outputs)

        # Check inputs
        expected_inputs = [(g.id, prop) for g in components.graphs
                           for prop in ["selectedData", "relayoutData"]
                           ] + [(components.resets[0].id, "n_clicks")]

        self.assertEqual(
            [(ip.component_id, ip.component_property) for ip in inputs],
            expected_inputs,
        )

        # Check State
        expected_state = [(components.store.id, "data")]
        self.assertEqual(
            [(state.component_id, state.component_property)
             for state in states],
            expected_state,
        )

        # Get callback function
        callback_fn = self.app.callback.return_value.call_args[0][0]

        # mimic initial callback invocation
        store_value = encode_store_data(
            {"streams": {
                id(rangexy): rangexy.contents
            }})
        with patch.object(
                CallbackContext, "triggered",
            [{
                "prop_id": components.graphs[0].id + ".relayoutData"
            }]):
            [fig1, fig2, new_store] = callback_fn({}, {
                "xaxis.range[0]": 1,
                "xaxis.range[1]": 3,
                "yaxis.range[0]": 2,
                "yaxis.range[1]": 4
            }, {}, {}, None, store_value)

        # First figure is the scatter trace
        self.assertEqual(fig1["data"][0]["type"], "scatter")

        # Second figure holds the bounds element
        self.assertEqual(len(fig2["data"]), 1)
        self.assertEqual(list(fig2["data"][0]["x"]), [1, 3])
        self.assertEqual(list(fig2["data"][0]["y"]), [2, 4])

        # Check updated store
        self.assertEqual(
            decode_store_data(new_store), {
                "streams": {
                    id(rangexy): {
                        'x_range': (1, 3),
                        'y_range': (2, 4)
                    }
                },
                "kdims": {}
            })
Exemple #23
0
    location = param.ObjectSelector(default='dropoff',
                                    objects=['dropoff', 'pickup'])

    def make_view(self, x_range, y_range, **kwargs):
        map_tiles = tiles(style=dict(alpha=self.alpha), plot=tile_options)
        points = hv.Points(df,
                           kdims=[self.location + '_x', self.location + '_y'],
                           vdims=['dropoff_hour'])
        if self.hour != (0, 24): points = points.select(dropoff_hour=self.hour)
        taxi_trips = datashade(points,
                               x_sampling=1,
                               y_sampling=1,
                               cmap=self.colormap,
                               dynamic=False,
                               x_range=x_range,
                               y_range=y_range,
                               width=1000,
                               height=600)
        return map_tiles * taxi_trips


selector = NYCTaxiExplorer(name="NYC Taxi Trips")
dmap = hv.DynamicMap(selector.make_view, streams=[selector, RangeXY()])
plot = hv.renderer('bokeh').instance(mode='server').get_plot(dmap)

parambokeh.Widgets(selector,
                   view_position='right',
                   callback=selector.event,
                   mode='server',
                   plots=[plot.state])
Exemple #24
0
class skyplot(ParameterizedFunction):
    """Skyplot of RA/dec switching between rasterized and raw data view.

    Colormapped by a third dimension.
    """

    aggregator = param.ObjectSelector(
        default="mean",
        objects=["mean", "std", "count"],
        doc="""
        Aggregator for datashading.""",
    )

    cmap = param.String(
        default="coolwarm",
        doc="""
        Colormap to use.""",
    )

    decimate_size = param.Number(
        default=5,
        doc="""
        Size of (invisible) decimated points.""",
    )

    max_points = param.Integer(
        default=10000,
        doc="""
        Maximum number of points to display before switching to rasterize.""",
    )

    vdim = param.String(
        default=None,
        doc="""
        Dimension to use for colormap.""",
    )

    ra_sampling = param.Integer(
        default=None,
        doc="""
        How densely to sample the rasterized plot along the x-axis.""",
    )

    dec_sampling = param.Integer(
        default=None,
        doc="""
        How densely to sample the rasterized plot along the y-axis.""",
    )

    filter_stream = param.ClassSelector(
        default=FilterStream(),
        class_=FilterStream,
        doc="""
        Filter stream to update plot with currently selected filters.""",
    )

    range_stream = param.ClassSelector(
        default=RangeXY(),
        class_=RangeXY,
        doc="""
        Range stream to share between plots to link and persist plot ranges.""",
    )

    flags = param.List(default=[], doc="Flags to select.")

    bad_flags = param.List(default=[], doc="Flags to ignore")

    def __call__(self, dset, **params):
        self.p = ParamOverrides(self, params)

        if self.p.vdim is None:
            vdim = dset.vdims[0].name
        else:
            vdim = self.p.vdim

        ra_range = (ra0, ra1) = dset.range("ra")
        if self.p.ra_sampling:
            xsampling = (ra1 - ra0) / self.p.ra_sampling
        else:
            xsampling = None

        dec_range = (dec0, dec1) = dset.range("dec")
        if self.p.dec_sampling:
            ysampling = (dec1 - dec0) / self.p.dec_sampling
        else:
            ysampling = None

        if self.p.aggregator == "mean":
            aggregator = ds.mean(vdim)
        elif self.p.aggregator == "std":
            aggregator = ds.std(vdim)
        elif self.p.aggregator == "count":
            aggregator = ds.count()

        sky_range = RangeXY()
        if self.p.range_stream:

            def redim(dset, x_range, y_range):
                ranges = {}
                if x_range and all(isfinite(v) for v in x_range):
                    ranges["ra"] = x_range
                if y_range and all(isfinite(v) for v in x_range):
                    ranges["dec"] = y_range
                return dset.redim.range(**ranges) if ranges else dset

            dset = dset.apply(redim, streams=[self.p.range_stream])
            link_streams(self.p.range_stream, sky_range)
        streams = [sky_range, PlotSize()]

        pts = dset.apply(skypoints, streams=[self.p.filter_stream])

        reset = PlotReset(source=pts)
        reset.add_subscriber(partial(reset_stream, None,
                                     [self.p.range_stream]))

        rasterize_inst = rasterize.instance(aggregator=aggregator,
                                            streams=streams,
                                            x_sampling=xsampling,
                                            y_sampling=ysampling)
        raster_pts = apply_when(
            pts,
            operation=rasterize_inst,
            predicate=lambda pts: len(pts) > self.p.max_points)
        return raster_pts.opts(
            opts.Image(
                bgcolor="black",
                colorbar=True,
                cmap=self.p.cmap,
                min_height=100,
                responsive=True,
                tools=["hover"],
                symmetric=True,
            ),
            opts.Points(
                color=vdim,
                cmap=self.p.cmap,
                framewise=True,
                size=self.p.decimate_size,
                tools=["hover"],
                symmetric=True,
            ),
            opts.Overlay(hooks=[
                partial(reset_hook, x_range=ra_range, y_range=dec_range)
            ]),
        )
Exemple #25
0
    def __call__(self, dset, **params):
        self.p = ParamOverrides(self, params)
        if self.p.xdim not in dset.dimensions():
            raise ValueError("{} not in Dataset.".format(self.p.xdim))
        if self.p.ydim not in dset.dimensions():
            raise ValueError("{} not in Dataset.".format(self.p.ydim))
        if ("ra" not in dset.dimensions()) or ("dec" not in dset.dimensions()):
            raise ValueError("ra and/or dec not in Dataset.")

        # Compute sampling
        ra_range = (ra0, ra1) = dset.range("ra")
        if self.p.ra_sampling:
            ra_sampling = (ra1 - ra0) / self.p.x_sampling
        else:
            ra_sampling = None

        dec_range = (dec0, dec1) = dset.range("dec")
        if self.p.dec_sampling:
            dec_sampling = (dec1 - dec0) / self.p.y_sampling
        else:
            dec_sampling = None

        x_range = (x0, x1) = dset.range(self.p.xdim)
        if self.p.x_sampling:
            x_sampling = (x1 - x0) / self.p.x_sampling
        else:
            x_sampling = None

        y_range = (y0, y1) = dset.range(self.p.ydim)
        if self.p.y_sampling:
            y_sampling = (y1 - y0) / self.p.y_sampling
        else:
            y_sampling = None

        # Set up scatter plot
        scatter_range = RangeXY()
        if self.p.scatter_range_stream:

            def redim_scatter(dset, x_range, y_range):
                ranges = {}
                if x_range and all(isfinite(v) for v in x_range):
                    ranges[self.p.xdim] = x_range
                if y_range and all(isfinite(v) for v in x_range):
                    ranges[self.p.ydim] = y_range
                return dset.redim.range(**ranges) if ranges else dset

            dset_scatter = dset.apply(redim_scatter,
                                      streams=[self.p.scatter_range_stream])
            link_streams(self.p.scatter_range_stream, scatter_range)
        else:
            dset_scatter = dset
        scatter_pts = dset_scatter.apply(filterpoints,
                                         streams=[self.p.filter_stream],
                                         xdim=self.p.xdim,
                                         ydim=self.p.ydim)
        scatter_streams = [scatter_range, PlotSize()]
        scatter_rasterize = rasterize.instance(streams=scatter_streams,
                                               x_sampling=x_sampling,
                                               y_sampling=y_sampling)
        cmap = (process_cmap(self.p.scatter_cmap)[:250]
                if self.p.scatter_cmap == "fire" else self.p.scatter_cmap)
        scatter_rasterized = apply_when(
            scatter_pts,
            operation=scatter_rasterize,
            predicate=lambda pts: len(pts) > self.p.max_points
        ).opts(
            opts.Image(clim=(1, np.nan),
                       clipping_colors={"min": "transparent"},
                       cmap=cmap),
            opts.Points(clim=(1, np.nan),
                        clipping_colors={"min": "transparent"},
                        cmap=cmap),
            opts.Overlay(
                hooks=[partial(reset_hook, x_range=x_range, y_range=y_range)]),
        )

        # Set up sky plot
        sky_range = RangeXY()
        if self.p.sky_range_stream:

            def redim_sky(dset, x_range, y_range):
                ranges = {}
                if x_range and all(isfinite(v) for v in x_range):
                    ranges["ra"] = x_range
                if y_range and all(isfinite(v) for v in x_range):
                    ranges["dec"] = y_range
                return dset.redim.range(**ranges) if ranges else dset

            dset_sky = dset.apply(redim_sky, streams=[self.p.sky_range_stream])
            link_streams(self.p.sky_range_stream, sky_range)
        else:
            dset_sky = dset
        sky_pts = dset_sky.apply(filterpoints,
                                 xdim="ra",
                                 ydim="dec",
                                 set_title=False,
                                 streams=[self.p.filter_stream])
        skyplot_streams = [sky_range, PlotSize()]
        sky_rasterize = rasterize.instance(
            aggregator=ds.mean(self.p.ydim),
            streams=skyplot_streams,
            x_sampling=ra_sampling,
            y_sampling=dec_sampling,
        )
        sky_rasterized = apply_when(
            sky_pts,
            operation=sky_rasterize,
            predicate=lambda pts: len(pts) > self.p.max_points).opts(
                opts.Image(bgcolor="black",
                           cmap=self.p.sky_cmap,
                           symmetric=True),
                opts.Points(bgcolor="black",
                            cmap=self.p.sky_cmap,
                            symmetric=True),
                opts.Overlay(hooks=[
                    partial(reset_hook, x_range=ra_range, y_range=dec_range)
                ]),
            )

        # Set up BoundsXY streams to listen to box_select events and notify FilterStream
        scatter_select = BoundsXY(source=scatter_pts)
        scatter_notifier = partial(notify_stream,
                                   filter_stream=self.p.filter_stream,
                                   xdim=self.p.xdim,
                                   ydim=self.p.ydim)
        scatter_select.add_subscriber(scatter_notifier)

        sky_select = BoundsXY(source=sky_pts)
        sky_notifier = partial(notify_stream,
                               filter_stream=self.p.filter_stream,
                               xdim="ra",
                               ydim="dec")
        sky_select.add_subscriber(sky_notifier)

        # Reset
        reset = PlotReset(source=sky_pts)
        reset.add_subscriber(
            partial(reset_stream, self.p.filter_stream,
                    [self.p.sky_range_stream, self.p.scatter_range_stream]))

        raw_scatterpts = filterpoints(dset, xdim=self.p.xdim, ydim=self.p.ydim)
        raw_scatter = datashade(
            raw_scatterpts,
            cmap=list(Greys9[::-1][:5]),
            streams=scatter_streams,
            x_sampling=x_sampling,
            y_sampling=y_sampling,
        )
        scatter_p = raw_scatter * scatter_rasterized

        if self.p.show_rawsky:
            raw_skypts = filterpoints(dset, xdim=self.p.xdim, ydim=self.p.ydim)
            raw_sky = datashade(
                rawskypts,
                cmap=list(Greys9[::-1][:5]),
                streams=skyplot_streams,
                x_sampling=ra_sampling,
                y_sampling=dec_sampling,
            )
            sky_p = raw_sky * sky_rasterized
        else:
            sky_p = sky_rasterized

        if self.p.show_table:
            table = dset.apply(summary_table,
                               ydim=self.p.ydim,
                               streams=[self.p.filter_stream])
            table = table.opts()
            layout = table + scatter_p + sky_p
        else:
            layout = (scatter_p + sky_p).opts(sizing_mode="stretch_width")

        return layout.opts(
            opts.Image(colorbar=True,
                       responsive=True,
                       tools=["box_select", "hover"]),
            opts.Layout(sizing_mode="stretch_width"),
            opts.Points(color=self.p.ydim, tools=["hover"]),
            opts.RGB(alpha=0.5),
            opts.Table(width=200),
        )