def test_decollate_overlay_of_dmaps(self): overlay = Overlay([ DynamicMap(lambda z: Points([z, z]), streams=[Z()]), DynamicMap(lambda z: Points([z, z]), streams=[Z()]), DynamicMap(lambda z: Points([z, z]), streams=[Z()]), ]) decollated = overlay.decollate() self.assertIsInstance(decollated, DynamicMap) self.assertEqual(len(decollated.streams), 3) expected = Overlay( [Points([1.0, 1.0]), Points([2.0, 2.0]), Points([3.0, 3.0])]) # Build result by updating streams decollated.streams[0].event(z=1.0) decollated.streams[1].event(z=2.0) decollated.streams[2].event(z=3.0) result = decollated[()] self.assertEqual(expected, result) # Build result by calling callback function result = decollated.callback.callable(dict(z=1.0), dict(z=2.0), dict(z=3.0)) self.assertEqual(expected, result)
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))
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)
def test_dynamic_values_partial_overlap(self): kdims = [Dimension('File', range=(0.01, 1)), Dimension('SliceDimension', values=['x', 'y', 'z']), Dimension('Coordinates', range=(0.01, 1))] dmap1 = DynamicMap(lambda x, y, z: Image(np.random.rand(10,10)), kdims=kdims) dmap2 = DynamicMap(lambda x: Curve(np.random.rand(10,2))*VLine(x), kdims=kdims[:1]) mpl_renderer.get_widget(dmap1 + dmap2, 'selection')
def test_dynamicmap_range_default(self): dimension = Dimension('X', range=(0., 5.), default=0.05) hmap = DynamicMap(lambda x: Curve([1, 2, 3]), kdims=[dimension]) widgets = bokeh_renderer.get_widget(hmap, 'widgets') widgets, dimensions, init_dim_vals = widgets.get_widgets() self.assertEqual(widgets[0]['default'], 0.05) self.assertEqual(init_dim_vals, '[0.050000000]')
def test_dynamicmap_unsorted_numeric_values_slider_plot_update(self): dims = [Dimension('N', values=[10, 5, 0])] dmap = DynamicMap(lambda N: Curve([1, N, 5]), kdims=dims) widgets = bokeh_renderer.get_widget(dmap, 'widgets') widgets.get_widgets() widgets.update((2,)) self.assertEqual(widgets.plot.current_key, (10,))
def test_buffer_stream_following(self): stream = Buffer(data={ 'x': np.array([1]), 'y': np.array([1]) }, following=True) dmap = DynamicMap(Curve, streams=[stream]) plot = bokeh_renderer.get_plot(dmap) x_range = plot.handles['x_range'] y_range = plot.handles['y_range'] self.assertEqual(x_range.start, 0) self.assertEqual(x_range.end, 2) self.assertEqual(y_range.start, 0) self.assertEqual(y_range.end, 2) stream.send({'x': np.array([2]), 'y': np.array([-1])}) self.assertEqual(x_range.start, 1) self.assertEqual(x_range.end, 2) self.assertEqual(y_range.start, -1) self.assertEqual(y_range.end, 1) stream.following = False stream.send({'x': np.array([3]), 'y': np.array([3])}) self.assertEqual(x_range.start, 1) self.assertEqual(x_range.end, 2) self.assertEqual(y_range.start, -1) self.assertEqual(y_range.end, 1)
def test_stream_cleanup(self): stream = Stream.define(str('Test'), test=1)() dmap = DynamicMap(lambda test: Curve([]), streams=[stream]) plot = bokeh_renderer.get_plot(dmap) self.assertTrue(bool(stream._subscribers)) plot.cleanup() self.assertFalse(bool(stream._subscribers))
def test_update_cds_columns(self): curve = DynamicMap(lambda a: Curve(range(10), a), kdims=['a']).redim.values(a=['a', 'b', 'c']) plot = bokeh_renderer.get_plot(curve) self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a', 'y']) self.assertEqual(plot.state.xaxis[0].axis_label, 'a') plot.update(('b',)) self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a', 'b', 'y']) self.assertEqual(plot.state.xaxis[0].axis_label, 'b')
def test_dynamicmap_values_default(self): values = [chr(65 + i) for i in range(10)] dimension = Dimension('X', values=values, default='C') hmap = DynamicMap(lambda x: Curve([1, 2, 3]), kdims=[dimension]) widgets = bokeh_renderer.get_widget(hmap, 'widgets') widgets, dimensions, init_dim_vals = widgets.get_widgets() self.assertEqual(widgets[0]['default'], '2') self.assertEqual(init_dim_vals, repr(['2']))
def test_point_stream_callback_clip(self): dmap = DynamicMap(lambda x, y: Points([(x, y)]), kdims=[], streams=[PointerXY()]) plot = bokeh_server_renderer.get_plot(dmap) bokeh_server_renderer(plot) plot.callbacks[0].on_msg({"x": -0.3, "y": 1.2}) data = plot.handles['source'].data self.assertEqual(data['x'], np.array([0])) self.assertEqual(data['y'], np.array([1]))
def test_dynamicmap_ndoverlay_shrink_number_of_items(self): selected = Stream.define('selected', items=3)() def callback(items): return NdOverlay({j: Overlay([Curve([1, 2, j])]) for j in range(items)}) dmap = DynamicMap(callback, streams=[selected]) plot = bokeh_renderer.get_plot(dmap) selected.event(items=2) self.assertEqual(len([r for r in plot.state.renderers if r.visible]), 2)
def test_callback_cleanup(self): stream = PointerX(x=0) dmap = DynamicMap(lambda x: Curve([x]), streams=[stream]) plot = bokeh_server_renderer.get_plot(dmap) self.assertTrue(bool(stream._subscribers)) self.assertTrue(bool(Callback._callbacks)) plot.cleanup() self.assertFalse(bool(stream._subscribers)) self.assertFalse(bool(Callback._callbacks))
def test_dynamic_subplot_remapping(self): # Checks that a plot is appropriately updated when reused def cb(X): return NdOverlay({i: Curve(np.arange(10)+i) for i in range(X-2, X)}) dmap = DynamicMap(cb, kdims=['X']).redim.range(X=(1, 10)) plot = mpl_renderer.get_plot(dmap) plot.update((3,)) for i, subplot in enumerate(plot.subplots.values()): self.assertEqual(subplot.cyclic_index, i+3) self.assertEqual(list(subplot.overlay_dims.values()), [i+1])
def test_bokeh_widgets_server_mode(self): dmap = DynamicMap(lambda X: Curve([]), kdims=['X']).redim.range(X=(0, 5)) widgets = bokeh_renderer.instance(mode='server').get_widget(dmap, None) div, widget = widgets.widgets['X'] self.assertIsInstance(widget, Slider) self.assertEqual(widget.value, 0) self.assertEqual(widget.start, 0) self.assertEqual(widget.end, 5) self.assertEqual(widget.step, 1) self.assertEqual(widgets.state.sizing_mode, 'fixed')
def test_batched_curve_subscribers_correctly_attached(self): posx = PointerX() opts = {'NdOverlay': dict(plot=dict(legend_limit=0)), 'Curve': dict(style=dict(line_color=Cycle(values=['red', 'blue'])))} overlay = DynamicMap(lambda x: NdOverlay({i: Curve([(i, j) for j in range(2)]) for i in range(2)}).opts(opts), kdims=[], streams=[posx]) plot = bokeh_renderer.get_plot(overlay) self.assertIn(plot.refresh, posx.subscribers) self.assertNotIn(list(plot.subplots.values())[0].refresh, posx.subscribers)
def test_overlay_params_dict_linked_stream(self): tap = Tap() def test(x): return Curve([1, 2, 3]) * VLine(x or 0) dmap = DynamicMap(test, streams={'x': tap.param.x}) plot = bokeh_renderer.get_plot(dmap) tap.event(x=1) _, vline_plot = plot.subplots.values() assert vline_plot.handles['glyph'].location == 1
def test_dynamic_subplot_creation(self): def cb(X): return NdOverlay({i: Curve(np.arange(10)+i) for i in range(X)}) dmap = DynamicMap(cb, kdims=['X']).redim.range(X=(1, 10)) plot = bokeh_renderer.get_plot(dmap) self.assertEqual(len(plot.subplots), 1) plot.update((3,)) self.assertEqual(len(plot.subplots), 3) for i, subplot in enumerate(plot.subplots.values()): self.assertEqual(subplot.cyclic_index, i)
def test_stream_callback_with_ids(self): dmap = DynamicMap(lambda x, y: Points([(x, y)]), kdims=[], streams=[PointerXY()]) plot = bokeh_server_renderer.get_plot(dmap) bokeh_server_renderer(plot) model = plot.state plot.callbacks[0].on_msg({"x": {'id': model.ref['id'], 'value': 0.5}, "y": {'id': model.ref['id'], 'value': 0.4}}) data = plot.handles['source'].data self.assertEqual(data['x'], np.array([0.5])) self.assertEqual(data['y'], np.array([0.4]))
def test_layout_dimensioned_stream_title_update(self): stream = Stream.define('Test', test=0)() dmap = DynamicMap(lambda test: Curve([]), kdims=['test'], streams=[stream]) layout = dmap + Curve([]) plot = mpl_renderer.get_plot(layout) self.assertIn('test: 0', plot.handles['title'].get_text()) stream.event(test=1) self.assertIn('test: 1', plot.handles['title'].get_text()) plot.cleanup() self.assertEqual(stream._subscribers, [])
def test_dimensioned_streams_with_dynamic_map_overlay_clone(self): time = Stream.define('Time', time=-3.0)() def crosshair(time): return VLine(time) * HLine(time) crosshair = DynamicMap(crosshair, kdims='time', streams=[time]) path = Path([]) t = crosshair * path html, _ = bokeh_renderer(t) self.assertIn('Bokeh Application', html)
def test_dynamic_streams_refresh(self): stream = PointerXY(x=0, y=0) dmap = DynamicMap(lambda x, y: Points([(x, y)]), kdims=[], streams=[stream]) plot = mpl_renderer.get_plot(dmap) pre = mpl_renderer(plot, fmt='png') plot.state.set_dpi(72) stream.event(x=1, y=1) post = mpl_renderer(plot, fmt='png') self.assertNotEqual(pre, post)
def test_grid_dimensioned_stream_title_update(self): stream = Stream.define('Test', test=0)() dmap = DynamicMap(lambda test: Curve([]), kdims=['test'], streams=[stream]) grid = GridMatrix({0: dmap, 1: Curve([])}, 'X') plot = bokeh_renderer.get_plot(grid) self.assertIn('test: 0', plot.handles['title'].text) stream.event(test=1) self.assertIn('test: 1', plot.handles['title'].text) plot.cleanup() self.assertEqual(stream._subscribers, [])
def test_stream_callback_single_call(self): def history_callback(x, history=deque(maxlen=10)): history.append(x) return Curve(list(history)) stream = PointerX(x=0) dmap = DynamicMap(history_callback, kdims=[], streams=[stream]) plot = plotly_renderer.get_plot(dmap) plotly_renderer(plot) for i in range(20): stream.event(x=i) state = plot.state self.assertEqual(state['data'][0]['x'], np.arange(10)) self.assertEqual(state['data'][0]['y'], np.arange(10, 20))
def test_batched_curve_subscribers_correctly_linked(self): # Checks if a stream callback is created to link batched plot # to the stream posx = PointerX() opts = {'NdOverlay': dict(plot=dict(legend_limit=0)), 'Curve': dict(style=dict(line_color=Cycle(values=['red', 'blue'])))} overlay = DynamicMap(lambda x: NdOverlay({i: Curve([(i, j) for j in range(2)]) for i in range(2)}).opts(opts), kdims=[], streams=[posx]) plot = bokeh_renderer.get_plot(overlay) self.assertEqual(len(Callback._callbacks), 1) key = list(Callback._callbacks.keys())[0] self.assertEqual(key, (id(plot.handles['plot']), id(PointerXCallback)))
def test_stream_callback_single_call(self): def history_callback(x, history=deque(maxlen=10)): history.append(x) return Curve(list(history)) stream = PointerX(x=0) dmap = DynamicMap(history_callback, kdims=[], streams=[stream]) plot = bokeh_server_renderer.get_plot(dmap) bokeh_server_renderer(plot) for i in range(20): stream.event(x=i) data = plot.handles['source'].data self.assertEqual(data['x'], np.arange(10)) self.assertEqual(data['y'], np.arange(10, 20))
def test_dynamic_subplot_remapping(self): # Checks that a plot is appropriately updated when reused def cb(X): return NdOverlay({i: Curve(np.arange(10)+i) for i in range(X-2, X)}) dmap = DynamicMap(cb, kdims=['X']).redim.range(X=(1, 10)) plot = bokeh_renderer.get_plot(dmap) plot.update((3,)) legend_labels = [item.label for item in plot.state.legend[0].items] self.assertEqual(legend_labels, [{'value': '1'}, {'value': '2'}]) colors = Cycle().values for i, (subplot, color) in enumerate(zip(plot.subplots.values(), colors[3:])): self.assertEqual(subplot.handles['glyph'].line_color, color) self.assertEqual(subplot.cyclic_index, i+3) self.assertEqual(list(subplot.overlay_dims.values()), [i+1])
def perform_decollate_dmap_container_streams(self, ContainerType): # Create container of DynamicMaps, each with kdims a and b. xy_stream = XY() fn = lambda x, y: Points([x, y]) data = [(0, DynamicMap(fn, streams=[xy_stream])), (1, DynamicMap(fn, streams=[xy_stream])), (2, DynamicMap(fn, streams=[xy_stream]))] container = ContainerType(data, kdims=["c"]) # Decollate container decollated = container.decollate() self.assertIsInstance(decollated, DynamicMap) self.assertEqual(len(decollated.kdims), 0) self.assertEqual(len(decollated.streams), 1) # Check result of instantiating decollate DynamicMap for particular # stream values decollated.streams[0].event(x=2.0, y=3.0) xy_stream.event(x=2.0, y=3.0) expected_data = [(d[0], d[1][()]) for d in data] expected = ContainerType(expected_data, kdims=["c"]) result = decollated[()] self.assertEqual(expected, result)
def test_dimensioned_streams_with_dynamic_callback_returns_layout(self): stream = Stream.define('aname', aname='a')() def cb(aname): x = np.linspace(0, 1, 10) y = np.random.randn(10) curve = Curve((x, y), group=aname) hist = Histogram(y) return (curve + hist).opts(shared_axes=False) m = DynamicMap(cb, kdims=['aname'], streams=[stream]) p = bokeh_renderer.get_plot(m) T = 'XYZT' stream.event(aname=T) self.assertIn('aname: ' + T, p.handles['title'].text, p.handles['title'].text) p.cleanup() self.assertEqual(stream._subscribers, [])
def test_stream_callback_single_call(self): def history_callback(x, history=deque(maxlen=10)): history.append(x) return Curve(list(history)) stream = PointerX(x=0) dmap = DynamicMap(history_callback, kdims=[], streams=[stream]) plot = mpl_renderer.get_plot(dmap) mpl_renderer(plot) for i in range(20): plot.state.set_dpi(72) stream.event(x=i) x, y = plot.handles['artist'].get_data() self.assertEqual(x, np.arange(10)) self.assertEqual(y, np.arange(10, 20))