def test_poly_draw_callback_with_vdims_no_color_index(self): polys = Polygons([{ 'x': [0, 2, 4], 'y': [0, 2, 0], 'A': 1 }], vdims=['A']).options(color_index=None) poly_draw = PolyDraw(source=polys) plot = bokeh_server_renderer.get_plot(polys) self.assertIsInstance(plot.callbacks[0], PolyDrawCallback) callback = plot.callbacks[0] data = { 'x': [[1, 2, 3], [3, 4, 5]], 'y': [[1, 2, 3], [3, 4, 5]], 'A': [1, 2] } callback.on_msg({'data': data}) element = Polygons([{ 'x': [1, 2, 3], 'y': [1, 2, 3], 'A': 1 }, { 'x': [3, 4, 5], 'y': [3, 4, 5], 'A': 2 }], vdims=['A']) self.assertEqual(poly_draw.element, element)
def test_multi_polygon_iloc_index_row(self): xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [[[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], []] poly = Polygons([{ 'x': xs, 'y': ys, 'holes': holes, 'z': 1 }, { 'x': xs[::-1], 'y': ys[::-1], 'z': 2 }], ['x', 'y'], 'z', datatype=[self.datatype]) expected = Polygons([{ 'x': xs, 'y': ys, 'holes': holes, 'z': 1 }], ['x', 'y'], 'z', datatype=[self.datatype]) self.assertIs(poly.interface, self.interface) self.assertEqual(poly.iloc[0], expected)
def test_select_from_multi_polygons_with_list(self): xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [[[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], []] poly = Polygons([{ 'x': xs, 'y': ys, 'holes': holes, 'z': 1 }, { 'x': xs[::-1], 'y': ys[::-1], 'z': 2 }, { 'x': xs[:3], 'y': ys[:3], 'z': 3 }], ['x', 'y'], 'z', datatype=[self.datatype]) expected = Polygons([{ 'x': xs, 'y': ys, 'holes': holes, 'z': 1 }, { 'x': xs[:3], 'y': ys[:3], 'z': 3 }], ['x', 'y'], 'z', datatype=[self.datatype]) self.assertIs(poly.interface, self.interface) self.assertEqual(poly.select(z=[1, 3]), expected)
def test_poly_edit_callback(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]]) poly_edit = PolyEdit(source=polys) plot = bokeh_server_renderer.get_plot(polys) self.assertIsInstance(plot.callbacks[0], PolyEditCallback) callback = plot.callbacks[0] data = {'x': [[1, 2, 3], [3, 4, 5]], 'y': [[1, 2, 3], [3, 4, 5]]} callback.on_msg({'data': data}) element = Polygons([[(1, 1), (2, 2), (3, 3)], [(3, 3), (4, 4), (5, 5)]]) self.assertEqual(poly_edit.element, element)
def test_box_edit_callback(self): boxes = Polygons([Box(0, 0, 1)]) box_edit = BoxEdit(source=boxes) plot = bokeh_server_renderer.get_plot(boxes) self.assertIsInstance(plot.callbacks[0], BoxEditCallback) callback = plot.callbacks[0] source = plot.handles['rect_source'] self.assertEqual(source.data, {'x': [0], 'y': [0], 'width': [1], 'height': [1]}) data = {'x': [0, 1], 'y': [0, 1], 'width': [0.5, 2], 'height': [2, 0.5]} callback.on_msg({'data': data}) element = Polygons([Box(0, 0, (0.5, 2)), Box(1, 1, (2, 0.5))]) self.assertEqual(box_edit.element, element)
def test_polygon_roundtrip(self): xs = [1, 2, 3] ys = [2, 0, 7] poly = Polygons([{'x': xs, 'y': ys, 'z': 0}, {'x': xs[::-1], 'y': ys[::-1], 'z': 1}], ['x', 'y'], 'z', datatype=[self.datatype]) self.assertIsInstance(poly.data.geometry.dtype, PolygonDtype) roundtrip = poly.clone(datatype=['multitabular']) self.assertEqual(roundtrip.interface.datatype, 'multitabular') expected = Polygons([{'x': xs+[1], 'y': ys+[2], 'z': 0}, {'x': [3]+xs, 'y': [7]+ys, 'z': 1}], ['x', 'y'], 'z', datatype=['multitabular']) self.assertEqual(roundtrip, expected)
def test_polygons_holes_initialize(self): from bokeh.models import MultiPolygons xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [ [[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], [] ] poly = HoloMap({0: Polygons([{'x': xs, 'y': ys, 'holes': holes}]), 1: Polygons([{'x': xs, 'y': ys}])}) plot = bokeh_renderer.get_plot(poly) glyph = plot.handles['glyph'] self.assertTrue(plot._has_holes) self.assertIsInstance(glyph, MultiPolygons)
def test_polygons_no_holes_with_draw_tool(self): from bokeh.models import Patches xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [ [[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], [] ] poly = HoloMap({0: Polygons([{'x': xs, 'y': ys, 'holes': holes}]), 1: Polygons([{'x': xs, 'y': ys}])}) PolyDraw(source=poly) plot = bokeh_renderer.get_plot(poly) glyph = plot.handles['glyph'] self.assertFalse(plot._has_holes) self.assertIsInstance(glyph, Patches)
def test_empty_polygons_plot(self): poly = Polygons([], vdims=['Intensity']) plot = bokeh_renderer.get_plot(poly) source = plot.handles['source'] self.assertEqual(len(source.data['xs']), 0) self.assertEqual(len(source.data['ys']), 0) self.assertEqual(len(source.data['Intensity']), 0)
def test_polygons_alpha_op(self): polygons = Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'alpha': 0.7}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'alpha': 0.3} ], vdims='alpha').options(alpha='alpha') with self.assertRaises(Exception): mpl_renderer.get_plot(polygons)
def test_polygon_to_path_patches(self): xs = [1, 2, 3, np.nan, 6, 7, 3, np.nan, 0, 0, 0] ys = [2, 0, 7, np.nan, 7, 5, 2, np.nan, 0, 1, 0] holes = [[[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], [], []] polys = Polygons([{'x': xs, 'y': ys, 'holes': holes}]) paths = polygons_to_path_patches(polys) self.assertEqual(len(paths), 1) self.assertEqual(len(paths[0]), 3) self.assertEqual( paths[0][0].get_path().vertices, np.array([(1, 2), (2, 0), (3, 7), (1, 2), (1.5, 2), (2, 3), (1.6, 1.6), (1.5, 2), (2.1, 4.5), (2.5, 5), (2.3, 3.5), (2.1, 4.5)])) self.assertEqual( paths[0][0].get_path().codes, np.array([1, 2, 2, 79, 1, 2, 2, 79, 1, 2, 2, 79], dtype='uint8')) self.assertEqual(paths[0][1].get_path().vertices, np.array([(6, 7), (7, 5), (3, 2), (6, 7)])) self.assertEqual(paths[0][1].get_path().codes, np.array([1, 2, 2, 79], dtype='uint8')) self.assertEqual(paths[0][2].get_path().vertices, np.array([(0, 0), (0, 1), (0, 0)])) self.assertEqual(paths[0][1].get_path().codes, np.array([1, 2, 2, 79], dtype='uint8'))
def test_poly_edit_callback_initialized_js(self): polys = Polygons([[(0, 0), (2, 2), (4, 0)]]) PolyEdit(source=polys) plot = bokeh_renderer.get_plot(polys) cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['source'].js_property_callbacks, {'change:data': [cb], 'patching': [cb]})
def test_multi_polygon_hole_plot(self): xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [[[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], []] poly = Polygons([{ 'x': xs, 'y': ys, 'holes': holes, 'value': 1 }], vdims=['value']) plot = mpl_renderer.get_plot(poly) artist = plot.handles['artist'] self.assertEqual(artist.get_array(), np.array([1, 1])) paths = artist.get_paths() self.assertEqual(len(paths), 2) path = paths[0] self.assertEqual( path.vertices, np.array([(1, 2), (2, 0), (3, 7), (1, 2), (1.5, 2), (2, 3), (1.6, 1.6), (1.5, 2), (2.1, 4.5), (2.5, 5), (2.3, 3.5), (2.1, 4.5)])) self.assertEqual(path.codes, np.array([1, 2, 2, 79, 1, 2, 2, 79, 1, 2, 2, 79])) path2 = paths[1] self.assertEqual(path2.vertices, np.array([(6, 7), (7, 5), (3, 2), (6, 7)])) self.assertEqual(path2.codes, np.array([1, 2, 2, 79]))
def test_data_link_mismatch(self): polys = Polygons([np.random.rand(10, 2)]) table = Table([('A', 1), ('B', 2)], 'A', 'B') DataLink(polys, table) layout = polys + table with self.assertRaises(Exception): bokeh_renderer.get_plot(layout)
def test_box_edit_callback_initialized_js(self): boxes = Polygons([Box(0, 0, 1)]) BoxEdit(source=boxes) plot = bokeh_renderer.get_plot(boxes) cb = plot.callbacks[0].callbacks[0] self.assertEqual(plot.handles['rect_source'].js_property_callbacks, {'change:data': [cb], 'patching': [cb]})
def test_polygons_overlay_hover(self): obj = NdOverlay({i: Polygons([np.random.rand(10,2)], vdims=['z'], level=0) for i in range(5)}, kdims=['Test']) opts = {'Polygons': {'tools': ['hover']}, 'NdOverlay': {'legend_limit': 0}} obj = obj(plot=opts) self._test_hover_info(obj, [('Test', '@{Test}'), ('z', '@{z}')])
def test_multi_polygon_constructor(self): xs = [1, 2, 3, np.nan, 6, 7, 3] ys = [2, 0, 7, np.nan, 7, 5, 2] holes = [[[(1.5, 2), (2, 3), (1.6, 1.6)], [(2.1, 4.5), (2.5, 5), (2.3, 3.5)]], []] path = Polygons([{ 'x': xs, 'y': ys, 'holes': holes }, { 'x': xs[::-1], 'y': ys[::-1] }], ['x', 'y'], datatype=[self.datatype]) self.assertIsInstance(path.data.geometry.dtype, MultiPolygonDtype) self.assertEqual( path.data.iloc[0, 0].buffer_values, np.array([ 1., 2., 2., 0., 3., 7., 1., 2., 1.5, 2., 2., 3., 1.6, 1.6, 1.5, 2., 2.1, 4.5, 2.5, 5., 2.3, 3.5, 2.1, 4.5, 6., 7., 3., 2., 7., 5., 6., 7. ])) self.assertEqual( path.data.iloc[1, 0].buffer_values, np.array([3, 2, 7, 5, 6, 7, 3, 2, 3, 7, 1, 2, 2, 0, 3, 7]))
def test_polygon_dtype(self): poly = Polygons([{ 'x': [1, 2, 3], 'y': [2, 0, 7] }], datatype=[self.datatype]) self.assertIs(poly.interface, self.interface) self.assertEqual(poly.interface.dtype(poly, 'x'), 'float64')
def test_polygons_line_width_op(self): polygons = Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'line_width': 7}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'line_width': 3} ], vdims='line_width').options(linewidth='line_width') plot = mpl_renderer.get_plot(polygons) artist = plot.handles['artist'] self.assertEqual(artist.get_linewidths(), [7, 3])
def test_polygons_colored(self): polygons = NdOverlay({j: Polygons([[(i**j, i) for i in range(10)]], level=j) for j in range(5)}) plot = mpl_renderer.get_plot(polygons) for j, splot in enumerate(plot.subplots.values()): artist = splot.handles['artist'] self.assertEqual(artist.get_array(), np.array([j])) self.assertEqual(artist.get_clim(), (0, 4))
def test_multi_polygon_expanded_values(self): xs = [1, 2, 3, np.nan, 1, 2, 3] ys = [2, 0, 7, np.nan, 2, 0, 7] poly = Polygons([{'x': xs, 'y': ys, 'z': 1}], ['x', 'y'], 'z', datatype=[self.datatype]) self.assertEqual(poly.dimension_values(0), np.array([1, 2, 3, 1, np.nan, 1, 2, 3, 1])) self.assertEqual(poly.dimension_values(1), np.array([2, 0, 7, 2, np.nan, 2, 0, 7, 2])) self.assertEqual(poly.dimension_values(2), np.array([1, 1, 1, 1, 1, 1, 1, 1, 1]))
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_polygons_categorical_color_op(self): polygons = Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'color': 'b'}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'color': 'a'} ], vdims='color').options(color='color') plot = mpl_renderer.get_plot(polygons) artist = plot.handles['artist'] self.assertEqual(artist.get_array(), np.array([0, 1])) self.assertEqual(artist.get_clim(), (0, 1))
def test_polygons_linear_color_op_update(self): polygons = HoloMap({ 0: Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'color': 7}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'color': 3} ], vdims='color'), 1: Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'color': 2}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'color': 5} ], vdims='color'), }).options(color='color', framewise=True) plot = mpl_renderer.get_plot(polygons) artist = plot.handles['artist'] self.assertEqual(artist.get_array(), np.array([7, 3])) self.assertEqual(artist.get_clim(), (3, 7)) plot.update((1,)) self.assertEqual(artist.get_array(), np.array([2, 5])) self.assertEqual(artist.get_clim(), (2, 5))
def test_polygons_linear_color_op(self): polygons = Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'color': 7}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'color': 3} ], vdims='color').options(color='color') plot = mpl_renderer.get_plot(polygons) artist = plot.handles['artist'] self.assertEqual(artist.get_array(), np.array([7, 3])) self.assertEqual(artist.get_clim(), (3, 7))
def test_selection_expr_stream_polygon_index_cols(self): # Create SelectionExpr on element try: import shapely # noqa except: try: import spatialpandas # noqa except: raise SkipTest('Shapely required for polygon selection') poly = Polygons([ [(0, 0, 'a'), (2, 0, 'a'), (1, 1, 'a')], [(2, 0, 'b'), (4, 0, 'b'), (3, 1, 'b')], [(1, 1, 'c'), (3, 1, 'c'), (2, 2, 'c')] ], vdims=['cat']) events = [] expr_stream = SelectionExpr(poly, index_cols=['cat']) expr_stream.add_subscriber(lambda **kwargs: events.append(kwargs)) # Check stream properties self.assertEqual(len(expr_stream.input_streams), 3) self.assertIsInstance(expr_stream.input_streams[0], SelectionXY) self.assertIsInstance(expr_stream.input_streams[1], Lasso) self.assertIsInstance(expr_stream.input_streams[2], Selection1D) self.assertIsNone(expr_stream.bbox) self.assertIsNone(expr_stream.selection_expr) expr_stream.input_streams[2].event(index=[0, 1]) self.assertEqual( repr(expr_stream.selection_expr), repr(dim('cat').isin(['a', 'b'])) ) self.assertEqual(expr_stream.bbox, None) self.assertEqual(len(events), 1) # Ensure bounds event does not trigger another update expr_stream.input_streams[0].event(bounds=(0, 0, 4, 1)) self.assertEqual( repr(expr_stream.selection_expr), repr(dim('cat').isin(['a', 'b'])) ) self.assertEqual(len(events), 1) # Ensure geometry event does trigger another update expr_stream.input_streams[1].event(geometry=np.array([(0, 0), (4, 0), (4, 2), (0, 2)])) self.assertEqual( repr(expr_stream.selection_expr), repr(dim('cat').isin(['a', 'b', 'c'])) ) self.assertEqual(len(events), 2) # Ensure index event does trigger another update expr_stream.input_streams[2].event(index=[1, 2]) self.assertEqual( repr(expr_stream.selection_expr), repr(dim('cat').isin(['b', 'c'])) ) self.assertEqual(expr_stream.bbox, None) self.assertEqual(len(events), 3)
def test_polygons_line_width_op(self): polygons = Polygons([ {('x', 'y'): [(0, 0), (0, 1), (1, 0)], 'line_width': 7}, {('x', 'y'): [(1, 0), (1, 1), (0, 1)], 'line_width': 3} ], vdims='line_width').options(line_width='line_width') plot = bokeh_renderer.get_plot(polygons) cds = plot.handles['source'] glyph = plot.handles['glyph'] self.assertEqual(glyph.line_width, {'field': 'line_width'}) self.assertEqual(cds.data['line_width'], np.array([7, 3]))
def test_polygons_colored(self): polygons = NdOverlay({j: Polygons([[(i**j, i) for i in range(10)]], level=j) for j in range(5)}) plot = bokeh_renderer.get_plot(polygons) for i, splot in enumerate(plot.subplots.values()): cmapper = splot.handles['color_mapper'] self.assertEqual(cmapper.low, 0) self.assertEqual(cmapper.high, 4) source = splot.handles['source'] self.assertEqual(source.data['Value'], np.array([i]))
def test_polygons_colored_batched(self): polygons = NdOverlay({j: Polygons([[(i**j, i) for i in range(10)]], level=j) for j in range(5)}).opts(plot=dict(legend_limit=0)) plot = list(bokeh_renderer.get_plot(polygons).subplots.values())[0] cmapper = plot.handles['color_mapper'] self.assertEqual(cmapper.low, 0) self.assertEqual(cmapper.high, 4) source = plot.handles['source'] self.assertEqual(plot.handles['glyph'].fill_color['transform'], cmapper) self.assertEqual(source.data['Value'], list(range(5)))
def test_data_link_poly_table_on_unlinked_clone(self): arr1 = np.random.rand(10, 2) arr2 = np.random.rand(10, 2) polys = Polygons([arr1, arr2]) table = Table([('A', 1), ('B', 2)], 'A', 'B') DataLink(polys, table) layout = polys.clone() + table.clone(link=False) plot = bokeh_renderer.get_plot(layout) cds = list(plot.state.select({'type': ColumnDataSource})) self.assertEqual(len(cds), 2)