def test_multi_df_dataset(self): if not pd: raise SkipTest('Pandas not available') arrays = [pd.DataFrame(np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]), columns=['x', 'y']) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) for i, ds in enumerate(mds.split()): self.assertEqual(ds, Path(arrays[i], kdims=['x', 'y'], datatype=['dataframe']))
def test_data_link_list(self): path = Path([[(0, 0, 0), (1, 1, 1), (2, 2, 2)]], vdims='color').options(color='color') table = Table([('A', 1), ('B', 2)], 'A', 'B') DataLink(path, table) layout = path + table plot = bokeh_renderer.get_plot(layout) path_plot, table_plot = (sp.subplots['main'] for sp in plot.subplots.values()) self.assertIs(path_plot.handles['source'], table_plot.handles['source'])
def test_varying_value_dimension_values_not_expanded(self): path = Path([{ 'x': [1, 2, 3, 4, 5], 'y': [0, 0, 1, 1, 2], 'value': np.arange(5) }, { 'x': [5, 4, 3, 2, 1], 'y': [2, 2, 1, 1, 0], 'value': np.full(5, 1) }], vdims='value', datatype=[self.datatype]) self.assertIs(path.interface, self.interface) values = path.dimension_values('value', expanded=False) self.assertEqual(values[0], np.array([0, 1, 2, 3, 4])) self.assertEqual(values[1], 1) self.assertIsInstance(values[1], np.int_)
def test_path_continuously_varying_alpha_op(self): xs = [1, 2, 3, 4] ys = xs[::-1] alpha = [0.1, 0.7, 0.3, 0.2] data = {'x': xs, 'y': ys, 'alpha': alpha} path = Path([data], vdims='alpha').options(alpha='alpha') with self.assertRaises(Exception): mpl_renderer.get_plot(path)
def test_array_shape(self): arrays = [ np.column_stack([np.arange(i, i + 2), np.arange(i, i + 2)]) for i in range(2) ] mds = Path(arrays, kdims=['x', 'y'], datatype=[self.datatype]) self.assertIs(mds.interface, self.interface) self.assertEqual(mds.shape, (2, 2))
def setUp(self): self.dmap_element = DynamicMap(lambda: Image([])) self.dmap_overlay = DynamicMap(lambda: Overlay([Curve([]), Points([])])) self.dmap_ndoverlay = DynamicMap(lambda: NdOverlay({0: Curve([]), 1: Curve([])})) self.element = Scatter([]) self.el1, self.el2 = Path([]), HLine(0) self.overlay = Overlay([self.el1, self.el2]) self.ndoverlay = NdOverlay({0: VectorField([]), 1: VectorField([])})
def test_multi_mixed_dims_raises(self): arrays = [{ 'x': range(10), 'y' if j else 'z': range(10) } for i in range(2) for j in range(2)] error = "None of the available storage backends were able to support the supplied data format." with self.assertRaisesRegexp(ValueError, error): mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular'])
def test_multi_mixed_interface_raises(self): arrays = [ np.random.rand(10, 2) if j else { 'x': range(10), 'y': range(10) } for i in range(2) for j in range(2) ] with self.assertRaises(DataError): Path(arrays, kdims=['x', 'y'], datatype=['multitabular'])
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()
def test_path_continuously_varying_line_width_op(self): xs = [1, 2, 3, 4] ys = xs[::-1] line_width = [1, 7, 3, 2] data = {'x': xs, 'y': ys, 'line_width': line_width} path = Path([data], vdims='line_width').options(linewidth='line_width') plot = mpl_renderer.get_plot(path) artist = plot.handles['artist'] self.assertEqual(artist.get_linewidths(), [1, 7, 3])
def test_multi_line_constructor(self): xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] path = Path([{'x': xs, 'y': ys}, {'x': xs[::-1], 'y': ys[::-1]}], ['x', 'y'], datatype=[self.datatype]) self.assertIsInstance(path.data.geometry.dtype, MultiLineDtype) self.assertEqual(path.data.iloc[0, 0].buffer_values, np.array([1, 2, 2, 0, 3, 7, 6, 7, 7, 5, 3, 2])) self.assertEqual(path.data.iloc[1, 0].buffer_values, np.array([3, 2, 7, 5, 6, 7, 3, 7, 2, 0, 1, 2]))
def test_rgb_selection_numeric(self): img = RGB(([0, 1, 2], [0, 1, 2, 3], np.random.rand(4, 3, 3))) expr, bbox, region = img._get_selection_expr_for_stream_value( bounds=(0.5, 1.5, 2.1, 3.1)) self.assertEqual(bbox, {'x': (0.5, 2.1), 'y': (1.5, 3.1)}) self.assertEqual( expr.apply(img, expanded=True, flat=False), np.array([[False, False, False], [False, False, False], [False, True, True], [False, True, True]])) self.assertEqual(region, Rectangles([(0.5, 1.5, 2.1, 3.1)]) * Path([]))
def test_segs_geom_selection_inverted(self): rect = Segments([(0, 1, 2, 3), (1, 3, 1.5, 4), (2.5, 4.2, 3.5, 4.8)]).opts(invert_axes=True) geom = np.array([(-0.4, -0.1), (3.2, -0.1), (3.2, 4.1), (-0.1, 4.2)]) expr, bbox, region = rect._get_selection_expr_for_stream_value(geometry=geom) self.assertEqual(bbox, {'y0': np.array([-0.4, 3.2, 3.2, -0.1]), 'x0': np.array([-0.1, -0.1, 4.1, 4.2]), 'y1': np.array([-0.4, 3.2, 3.2, -0.1]), 'x1': np.array([-0.1, -0.1, 4.1, 4.2])}) self.assertEqual(expr.apply(rect), np.array([True, False, False])) self.assertEqual(region, Rectangles([]) * Path([list(geom)+[(-0.4, -0.1)]]))
def test_batched_path_line_width_and_color(self): opts = {'NdOverlay': dict(plot=dict(legend_limit=0)), 'Path': dict(style=dict(line_width=Cycle(values=[0.5, 1])))} overlay = NdOverlay({i: Path([[(i, j) for j in range(2)]]) for i in range(2)}).opts(opts) plot = bokeh_renderer.get_plot(overlay).subplots[()] line_width = [0.5, 1.] color = ['#30a2da', '#fc4f30'] self.assertEqual(plot.handles['source'].data['line_width'], line_width) self.assertEqual(plot.handles['source'].data['color'], color)
def test_poly_selection_numeric_inverted(self): poly = Polygons([ [(0, 0), (0.2, 0.1), (0.3, 0.4), (0.1, 0.2)], [(0.25, -.1), (0.4, 0.2), (0.6, 0.3), (0.5, 0.1)], [(0.3, 0.3), (0.5, 0.4), (0.6, 0.5), (0.35, 0.45)] ]).opts(invert_axes=True) expr, bbox, region = poly._get_selection_expr_for_stream_value(bounds=(0.2, -0.2, 0.6, 0.6)) self.assertEqual(bbox, {'y': (0.2, 0.6), 'x': (-0.2, 0.6)}) self.assertEqual(expr.apply(poly, expanded=False), np.array([False, False, True])) self.assertEqual(region, Rectangles([(0.2, -0.2, 0.6, 0.6)]) * Path([]))
def test_image_selection_numeric_inverted(self): img = Image(([0, 1, 2], [0, 1, 2, 3], np.random.rand(4, 3))).opts(invert_axes=True) expr, bbox, region = img._get_selection_expr_for_stream_value(bounds=(1.5, 0.5, 3.1, 2.1)) self.assertEqual(bbox, {'x': (0.5, 2.1), 'y': (1.5, 3.1)}) self.assertEqual(expr.apply(img, expanded=True, flat=False), np.array([ [False, False, False], [False, False, False], [False, True, True], [False, True, True] ])) self.assertEqual(region, Rectangles([(1.5, 0.5, 3.1, 2.1)]) * Path([]))
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_path_continuously_varying_line_width_op(self): xs = [1, 2, 3, 4] ys = xs[::-1] line_width = [1, 7, 3, 2] data = {'x': xs, 'y': ys, 'line_width': line_width} path = Path([data], vdims='line_width').options(line_width='line_width') plot = bokeh_renderer.get_plot(path) source = plot.handles['source'] self.assertEqual(source.data['xs'], [np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]) self.assertEqual(source.data['ys'], [np.array([4, 3]), np.array([3, 2]), np.array([2, 1])]) self.assertEqual(source.data['line_width'], np.array([1, 7, 3]))
def test_path_continuously_varying_alpha_op(self): xs = [1, 2, 3, 4] ys = xs[::-1] alpha = [0.1, 0.7, 0.3, 0.2] data = {'x': xs, 'y': ys, 'alpha': alpha} path = Path([data], vdims='alpha').options(alpha='alpha') plot = bokeh_renderer.get_plot(path) source = plot.handles['source'] self.assertEqual(source.data['xs'], [np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]) self.assertEqual(source.data['ys'], [np.array([4, 3]), np.array([3, 2]), np.array([2, 1])]) self.assertEqual(source.data['alpha'], np.array([0.1, 0.7, 0.3]))
def test_path_colored_and_split_on_single_value(self): xs = [1, 2, 3, 4] ys = xs[::-1] color = [1, 1, 1, 1] data = {'x': xs, 'y': ys, 'color': color} path = Path([data], vdims=['color']).options(color_index='color') plot = bokeh_renderer.get_plot(path) source = plot.handles['source'] self.assertEqual(source.data['xs'], [np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]) self.assertEqual(source.data['ys'], [np.array([4, 3]), np.array([3, 2]), np.array([2, 1])]) self.assertEqual(source.data['color'], np.array([1, 1, 1]))
def test_poly_geom_selection_inverted(self): poly = Polygons([ [(0, 0), (0.2, 0.1), (0.3, 0.4), (0.1, 0.2)], [(0.25, -.1), (0.4, 0.2), (0.6, 0.3), (0.5, 0.1)], [(0.3, 0.3), (0.5, 0.4), (0.6, 0.5), (0.35, 0.45)] ]).opts(invert_axes=True) geom = np.array([(0.2, -0.15), (0.5, 0), (0.75, 0.6), (0.1, 0.6)]) expr, bbox, region = poly._get_selection_expr_for_stream_value(geometry=geom) self.assertEqual(bbox, {'y': np.array([0.2, 0.5, 0.75, 0.1]), 'x': np.array([-0.15, 0, 0.6, 0.6])}) self.assertEqual(expr.apply(poly, expanded=False), np.array([False, False, True])) self.assertEqual(region, Rectangles([]) * Path([list(geom)+[(0.2, -0.15)]]))
def test_path_continuously_varying_color_op(self): xs = [1, 2, 3, 4] ys = xs[::-1] color = [998, 999, 998, 994] data = {'x': xs, 'y': ys, 'color': color} levels = [0, 38, 73, 95, 110, 130, 156, 999] colors = ['#5ebaff', '#00faf4', '#ffffcc', '#ffe775', '#ffc140', '#ff8f20', '#ff6060'] path = Path([data], vdims='color').options( color='color', color_levels=levels, cmap=colors) plot = mpl_renderer.get_plot(path) artist = plot.handles['artist'] self.assertEqual(artist.get_array(), np.array(color)) self.assertEqual(artist.get_clim(), (994, 999))
def test_segments_selection_numeric(self): segs = Segments([(0, 1, 2, 3), (1, 3, 1.5, 4), (2.5, 4.2, 3.5, 4.8)]) expr, bbox, region = segs._get_selection_expr_for_stream_value( bounds=(0.5, 0.9, 3.4, 4.9)) self.assertEqual(bbox, { 'x0': (0.5, 3.4), 'y0': (0.9, 4.9), 'x1': (0.5, 3.4), 'y1': (0.9, 4.9) }) self.assertEqual(expr.apply(segs), np.array([False, True, False])) self.assertEqual(region, Rectangles([(0.5, 0.9, 3.4, 4.9)]) * Path([])) expr, bbox, region = segs._get_selection_expr_for_stream_value( bounds=(0, 0.9, 3.5, 4.9)) self.assertEqual(bbox, { 'x0': (0, 3.5), 'y0': (0.9, 4.9), 'x1': (0, 3.5), 'y1': (0.9, 4.9) }) self.assertEqual(expr.apply(segs), np.array([True, True, True])) self.assertEqual(region, Rectangles([(0, 0.9, 3.5, 4.9)]) * Path([]))
def test_img_selection_geom_inverted(self): img = Image(([0, 1, 2], [0, 1, 2, 3], np.random.rand(4, 3))).opts(invert_axes=True) geom = np.array([(-0.4, -0.1), (0.6, -0.1), (0.4, 1.7), (-0.1, 1.7)]) expr, bbox, region = img._get_selection_expr_for_stream_value(geometry=geom) self.assertEqual(bbox, {'y': np.array([-0.4, 0.6, 0.4, -0.1]), 'x': np.array([-0.1, -0.1, 1.7, 1.7])}) self.assertEqual(expr.apply(img, expanded=True, flat=False), np.array([ [ True, True, False], [ False, False, False], [ False, False, False], [False, False, False] ])) self.assertEqual(region, Rectangles([]) * Path([list(geom)+[(-0.4, -0.1)]]))
def test_rect_selection_numeric_inverted(self): rect = Rectangles([(0, 1, 2, 3), (1, 3, 1.5, 4), (2.5, 4.2, 3.5, 4.8)]).opts(invert_axes=True) expr, bbox, region = rect._get_selection_expr_for_stream_value( bounds=(0.9, 0.5, 4.9, 3.4)) self.assertEqual(bbox, { 'x0': (0.5, 3.4), 'y0': (0.9, 4.9), 'x1': (0.5, 3.4), 'y1': (0.9, 4.9) }) self.assertEqual(expr.apply(rect), np.array([False, True, False])) self.assertEqual(region, Rectangles([(0.9, 0.5, 4.9, 3.4)]) * Path([])) expr, bbox, region = rect._get_selection_expr_for_stream_value( bounds=(0.9, 0, 4.9, 3.5)) self.assertEqual(bbox, { 'x0': (0, 3.5), 'y0': (0.9, 4.9), 'x1': (0, 3.5), 'y1': (0.9, 4.9) }) self.assertEqual(expr.apply(rect), np.array([True, True, True])) self.assertEqual(region, Rectangles([(0.9, 0, 4.9, 3.5)]) * Path([]))
def test_scalar_and_unique_values_isscalar_per_geom(self): path = Path([{ 'x': [1, 2, 3, 4, 5], 'y': [0, 0, 1, 1, 2], 'value': 0 }, { 'x': [5, 4, 3, 2, 1], 'y': [2, 2, 1, 1, 0], 'value': np.full(5, 1) }], vdims='value', datatype=[self.datatype]) self.assertIs(path.interface, self.interface) self.assertTrue(path.interface.isscalar(path, 'value', per_geom=True))
def test_multi_nonconstant_kdims_raises(self): arrays = [{ 'x': range(10), 'y': range(10), 'z': range(10) } for i in range(2)] error = ( "z' key dimension value must have a constant value on each subpath, " "for paths with value for each coordinate of the array declare a " "value dimension instead.") with self.assertRaisesRegexp(ValueError, error): mds = Path(arrays, kdims=['x', 'y', 'z'], datatype=['multitabular'])
def test_varying_values_and_scalar_not_isscalar_per_geom(self): path = Path([{ 'x': [1, 2, 3, 4, 5], 'y': [0, 0, 1, 1, 2], 'value': np.arange(5) }, { 'x': [5, 4, 3, 2, 1], 'y': [2, 2, 1, 1, 0], 'value': 1 }], vdims='value', datatype=[self.datatype]) self.assertIs(path.interface, self.interface) self.assertFalse(path.interface.isscalar(path, 'value', per_geom=True))
def test_points_selection_geom_inverted(self): points = Points([3, 2, 1, 3, 4]).opts(invert_axes=True) geom = np.array([(-0.1, -0.1), (1.4, 0), (1.4, 2.2), (-0.1, 2.2)]) expr, bbox, region = points._get_selection_expr_for_stream_value( geometry=geom) self.assertEqual( bbox, { 'y': np.array([-0.1, 1.4, 1.4, -0.1]), 'x': np.array([-0.1, 0, 2.2, 2.2]) }) self.assertEqual(expr.apply(points), np.array([False, False, True, False, False])) self.assertEqual(region, Rectangles([]) * Path([list(geom) + [(-0.1, -0.1)]]))
def test_path_colored_and_split_with_extra_vdims(self): xs = [1, 2, 3, 4] ys = xs[::-1] color = [0, 0.25, 0.5, 0.75] other = ['A', 'B', 'C', 'D'] data = {'x': xs, 'y': ys, 'color': color, 'other': other} path = Path([data], vdims=['color','other']).options(color_index='color', tools=['hover']) plot = bokeh_renderer.get_plot(path) source = plot.handles['source'] self.assertEqual(source.data['xs'], [np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]) self.assertEqual(source.data['ys'], [np.array([4, 3]), np.array([3, 2]), np.array([2, 1])]) self.assertEqual(source.data['other'], np.array(['A', 'B', 'C'])) self.assertEqual(source.data['color'], np.array([0, 0.25, 0.5]))
def test_path_continuously_varying_line_width_op_update(self): xs = [1, 2, 3, 4] ys = xs[::-1] path = HoloMap({ 0: Path([{ 'x': xs, 'y': ys, 'line_width': [1, 7, 3, 2] }], vdims='line_width'), 1: Path([{ 'x': xs, 'y': ys, 'line_width': [3, 8, 2, 3] }], vdims='line_width') }).options(linewidth='line_width') plot = mpl_renderer.get_plot(path) artist = plot.handles['artist'] self.assertEqual(artist.get_linewidths(), [1, 7, 3]) plot.update((1, )) self.assertEqual(artist.get_linewidths(), [3, 8, 2])
def test_multi_array_dataset(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) for i, ds in enumerate(mds.split()): self.assertEqual(ds, Path(arrays[i], kdims=['x', 'y'], datatype=['array']))
def test_multi_array_values(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) self.assertEqual(mds.dimension_values(0), np.array([0., 1, np.NaN, 1, 2]))
def test_multi_array_values_coordinates_nonexpanded_constant_kdim(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2), np.ones(2)*i]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], vdims=['z'], datatype=['multitabular']) self.assertEqual(mds.dimension_values(2, expanded=False), np.array([0, 1]))
def test_multi_split(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) for arr1, arr2 in zip(mds.split(datatype='array'), arrays): self.assertEqual(arr1, arr2)
def test_multi_split_empty(self): mds = Path([], kdims=['x', 'y'], datatype=['multitabular']) self.assertEqual(len(mds.split()), 0)
def test_multi_dict_dataset(self): arrays = [{'x': np.arange(i, i+2), 'y': np.arange(i, i+2)} for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) for i, ds in enumerate(mds.split()): self.assertEqual(ds, Path(arrays[i], kdims=['x', 'y'], datatype=['dictionary']))
def test_multi_array_dataset_add_dimension_scalar(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']).add_dimension('A', 0, 'Scalar', True) for i, ds in enumerate(mds.split()): self.assertEqual(ds, Path({('x', 'y'): arrays[i], 'A': 'Scalar'}, ['x', 'y'], 'A', datatype=['dictionary']))
def test_multi_array_range(self): arrays = [np.column_stack([np.arange(i, i+2), np.arange(i, i+2)]) for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']) self.assertEqual(mds.range(0), (0, 2))
def test_multi_dict_dataset_add_dimension_values(self): arrays = [{'x': np.arange(i, i+2), 'y': np.arange(i, i+2)} for i in range(2)] mds = Path(arrays, kdims=['x', 'y'], datatype=['multitabular']).add_dimension('A', 0, [0,1], True) for i, ds in enumerate(mds.split()): self.assertEqual(ds, Path(dict(arrays[i], A=i), ['x', 'y'], 'A', datatype=['dictionary']))
def test_multi_values_empty(self): mds = Path([], kdims=['x', 'y'], datatype=['multitabular']) self.assertEqual(mds.dimension_values(0), np.array([]))
def test_multi_empty_range(self): mds = Path([], kdims=['x', 'y'], datatype=['multitabular']) low, high = mds.range(0) self.assertFalse(np.isfinite(np.NaN)) self.assertFalse(np.isfinite(np.NaN))