def test_dynamic_overlay_memoization(self): """Tests that Callable memoizes unchanged callbacks""" def fn(x, y): return Scatter([(x, y)]) dmap = DynamicMap(fn, kdims=[], streams=[PointerXY()]) counter = [0] def fn2(x, y): counter[0] += 1 return Image(np.random.rand(10, 10)) dmap2 = DynamicMap(fn2, kdims=[], streams=[PointerXY()]) overlaid = dmap * dmap2 overlay = overlaid[()] self.assertEqual(overlay.Scatter.I, fn(0, 0)) dmap.event(x=1, y=2) overlay = overlaid[()] # Ensure dmap return value was updated self.assertEqual(overlay.Scatter.I, fn(1, 2)) # Ensure dmap2 callback was called only once self.assertEqual(counter[0], 1)
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_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_simple_constructor_streams_invalid_mismatch_named(self): def foo(x): return x regexp = "Callable 'foo' missing keywords to accept stream parameters: y" with self.assertRaisesRegexp(KeyError, regexp): DynamicMap(foo, streams=[PointerXY()])
def test_dynamic_operation_on_element_dict(self): img = Image(sine_array(0,5)) posxy = PointerXY(x=3, y=1) dmap_with_fn = Dynamic(img, operation=lambda obj, x, y: obj.clone(obj.data*x+y), streams=dict(x=posxy.param.x, y=posxy.param.y)) element = dmap_with_fn[()] self.assertEqual(element, Image(sine_array(0,5)*3+1))
def test_dynamic_event_renaming_valid(self): def fn(x1, y1): return Scatter([(x1, y1)]) xy = PointerXY(rename={'x': 'x1', 'y': 'y1'}) dmap = DynamicMap(fn, kdims=[], streams=[xy]) dmap.event(x1=1, y1=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_dynamic_operation_on_element(self): img = Image(sine_array(0,5)) posxy = PointerXY(x=2, y=1) dmap_with_fn = Dynamic(img, operation=lambda obj, x, y: obj.clone(obj.data*x+y), streams=[posxy]) element = dmap_with_fn[()] self.assertEqual(element, Image(sine_array(0,5)*2+1)) self.assertEqual(dmap_with_fn.streams, [posxy])
def test_dynamic_collate_layout_raise_ambiguous_remapping_error(self): def callback(x, y): return Image(np.array([[0, 1], [2, 3]])) + Image(np.array([[0, 1], [2, 3]])) stream = PointerXY() cb_callable = Callable(callback, stream_mapping={'Image': [stream]}) dmap = DynamicMap(cb_callable, kdims=[], streams=[stream]) with self.assertRaisesRegexp(ValueError, 'The stream_mapping supplied on the Callable is ambiguous'): dmap.collate()
def test_dynamic_collate_layout_raise_no_remapping_error(self): def callback(x, y): return Image(np.array([[0, 1], [2, 3]])) + Text(0, 0, 'Test') stream = PointerXY() cb_callable = Callable(callback) dmap = DynamicMap(cb_callable, kdims=[], streams=[stream]) with self.assertRaisesRegexp(ValueError, 'The following streams are set to be automatically linked'): dmap.collate()
def test_stream_callback_on_clone(self): points = Points([]) stream = PointerXY(source=points) plot = bokeh_server_renderer.get_plot(points.clone()) bokeh_server_renderer(plot) plot.callbacks[0].on_msg({"x": 0.8, "y": 0.3}) self.assertEqual(stream.x, 0.8) self.assertEqual(stream.y, 0.3)
def test_dynamic_collate_ndlayout_with_key_stream_mapping(self): def callback(x, y): return NdLayout({i: Image(np.array([[i, 1], [2, 3]])) for i in range(1, 3)}) stream = PointerXY() cb_callable = Callable(callback, stream_mapping={(1,): [stream]}) dmap = DynamicMap(cb_callable, kdims=[], streams=[stream]) layout = dmap.collate() self.assertEqual(list(layout.keys()), [1, 2]) self.assertIs(stream.source, layout[1])
def test_dynamic_collate_layout_with_spec_stream_mapping(self): def callback(x, y): return Image(np.array([[0, 1], [2, 3]])) + Text(0, 0, 'Test') stream = PointerXY() cb_callable = Callable(callback, stream_mapping={'Image': [stream]}) dmap = DynamicMap(cb_callable, kdims=[], streams=[stream]) layout = dmap.collate() self.assertEqual(list(layout.keys()), [('Image', 'I'), ('Text', 'I')]) self.assertIs(stream.source, layout.Image.I)
def test_dynamic_event_renaming_invalid(self): def fn(x1, y1): return Scatter([(x1, y1)]) xy = PointerXY(rename={'x': 'x1', 'y': 'y1'}) dmap = DynamicMap(fn, kdims=[], streams=[xy]) regexp = '(.+?)do not correspond to stream parameters' with self.assertRaisesRegexp(KeyError, regexp): dmap.event(x=1, y=2)
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_dynamic_collate_grid_with_key_stream_mapping(self): def callback(): return GridSpace({(i, j): Image(np.array([[i, j], [2, 3]])) for i in range(1, 3) for j in range(1, 3)}) stream = PointerXY() cb_callable = Callable(callback, stream_mapping={(1, 2): [stream]}) dmap = DynamicMap(cb_callable, kdims=[]) grid = dmap.collate() self.assertEqual(list(grid.keys()), [(i, j) for i in range(1, 3) for j in range(1, 3)]) self.assertEqual(stream.source, grid[(1, 2)])
def test_no_streams_one_stream_substitution(self): result = wrap_tuple_streams( (None, 3), [Dimension('x'), Dimension('y')], [PointerXY(x=-5, y=10)]) self.assertEqual(result, (-5, 3))
def get_timeseries(source, data, dataset, ymin, ymax, fmt): ''' get time series plots ''' #initialize timeseries_data if data.init is False: #find the maximum side length x, y = dataset['SCHISM_hgrid_node_x'].data, dataset[ 'SCHISM_hgrid_node_y'].data e1, e2, e3 = dataset['SCHISM_hgrid_face_nodes'].data.T s1 = abs((x[e1] - x[e2]) + 1j * (y[e1] - y[e2])).max() s2 = abs((x[e2] - x[e3]) + 1j * (y[e2] - y[e3])).max() s3 = abs((x[e3] - x[e1]) + 1j * (y[e3] - y[e1])).max() #save data data.sx, data.sy, data.x0, data.y0 = x, y, x.mean(), y.mean() data.mdist = np.max([s1, s2, s3]) data.time = dataset['time'].data data.xys = [] data.elev = [] data.curve = [] data.init = True def get_plot_point(x, y): if None not in [x, y]: add_remove_pts(x, y, data, dataset, fmt) if ((x is None) or (y is None)) and len(data.xys) == 0: xys = [(data.x0, data.y0)] hpoint = gv.Points(xys).opts(show_legend=False, visible=False) htext = gv.HoloMap({ i: gv.Text(*xy, '{}'.format(i + 1)).opts(show_legend=False, visible=False) for i, xy in enumerate(xys) }).overlay() else: xys = data.xys hpoint = gv.Points(xys).opts(color='r', size=3, show_legend=False) htext = gv.HoloMap({ i: gv.Text(*xy, '{}'.format(i + 1)).opts(show_legend=False, color='k', fontsize=3) for i, xy in enumerate(xys) }).overlay() return hpoint * htext def get_plot_curve(x, y): mdist, mdata = extract_timeseries(x, y, data.sx, data.sy, dataset) if mdist > data.mdist: mdata = mdata * np.nan hdynamic = hv.Curve((data.time, mdata)).opts(color='k', line_width=2, line_dash='dotted') hcurve = hv.HoloMap({ 'dynamic': hdynamic, **{(i + 1): k for i, k in enumerate(data.curve)} }).overlay() return hcurve hpoint = gv.DynamicMap(get_plot_point, streams=[DoubleTap(source=source, transient=True)]) hcurve = gv.DynamicMap(get_plot_curve, streams=[ PointerXY(x=data.x0, y=data.y0, source=source) ]).opts(height=400, legend_cols=len(data.xys) + 1, legend_position='top', ylim=(float(ymin), float(ymax)), responsive=True, align='end', active_tools=["pan", "wheel_zoom"]) return hpoint, hcurve
def test_simple_constructor_streams_invalid_mismatch(self): regexp = "Callable '<lambda>' missing keywords to accept stream parameters: y" with self.assertRaisesRegexp(KeyError, regexp): DynamicMap(lambda x: x, streams=[PointerXY()])
def test_stream_callback_on_unlinked_clone(self): points = Points([]) PointerXY(source=points) plot = bokeh_server_renderer.get_plot(points.clone(link=False)) bokeh_server_renderer(plot) self.assertTrue(len(plot.callbacks) == 0)
def test_simple_constructor_positional_stream_args(self): DynamicMap(lambda v: v, streams=[PointerXY()], positional_stream_args=True)
def test_no_streams_two_stream_substitution(self): result = wrap_tuple_streams( (None, None), [Dimension('x'), Dimension('y')], [PointerXY(x=0, y=5)]) self.assertEqual(result, (0, 5))