Exemple #1
0
 def test_graph_op_edge_line_width_update(self):
     graph = HoloMap({
         0: Graph([(0, 1, 2), (0, 2, 0.5), (1, 3, 3)],
                 vdims='line_width'),
         1: Graph([(0, 1, 4.3), (0, 2, 1.4), (1, 3, 2.6)],
                  vdims='line_width')}).options(edge_linewidth='line_width')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_linewidths(), [2, 0.5, 3])
     plot.update((1,))
     self.assertEqual(edges.get_linewidths(), [4.3, 1.4, 2.6])
Exemple #2
0
 def test_graph_op_edge_color_linear_update(self):
     graph = HoloMap({
         0: Graph([(0, 1, 2), (0, 2, 0.5), (1, 3, 3)],
                 vdims='color'),
         1: Graph([(0, 1, 4.3), (0, 2, 1.4), (1, 3, 2.6)],
                  vdims='color')}).options(edge_color='color', framewise=True)
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_array(), np.array([2, 0.5, 3]))
     self.assertEqual(edges.get_clim(), (0.5, 3))
     plot.update((1,))
     self.assertEqual(edges.get_array(), np.array([4.3, 1.4, 2.6]))
     self.assertEqual(edges.get_clim(), (1.4, 4.3))
    def setUp(self):
        super(TestBokehGraphPlot, self).setUp()

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights),), vdims='Weight')
Exemple #4
0
 def test_graph_op_edge_color_categorical(self):
     edges = [(0, 1, 'C'), (0, 2, 'B'), (1, 3, 'A')]
     graph = Graph(edges, vdims='color').options(edge_color='color')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_array(), np.array([0, 1, 2]))
     self.assertEqual(edges.get_clim(), (0, 2))
Exemple #5
0
 def test_graph_op_node_linewidth(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 3.5)], vdims='line_width')
     graph = Graph((edges, nodes)).options(node_linewidth='line_width')
     plot = mpl_renderer.get_plot(graph)
     artist = plot.handles['nodes']
     self.assertEqual(artist.get_linewidths(), [2, 4, 3.5])
Exemple #6
0
 def test_graph_op_edge_linewidth(self):
     edges = [(0, 1, 2), (0, 2, 10), (1, 3, 6)]
     graph = Graph(edges,
                   vdims='line_width').options(edge_linewidth='line_width')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_linewidths(), [2, 10, 6])
 def test_graph_op_node_alpha(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 0.2), (0, 1, 1, 0.6), (1, 1, 2, 1)],
                   vdims='alpha')
     graph = Graph((edges, nodes)).options(node_alpha='alpha')
     with self.assertRaises(Exception):
         mpl_renderer.get_plot(graph)
Exemple #8
0
 def test_graph_op_node_size(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 6)], vdims='size')
     graph = Graph((edges, nodes)).options(node_size='size')
     plot = mpl_renderer.get_plot(graph)
     artist = plot.handles['nodes']
     self.assertEqual(artist.get_sizes(), np.array([4, 16, 36]))
    def setUp(self):
        if not bokeh_renderer:
            raise SkipTest("Bokeh required to test plot instantiation")
        elif bokeh_version < str('0.12.9'):
            raise SkipTest("Bokeh >= 0.12.9 required to test graphs")
        self.previous_backend = Store.current_backend
        Store.current_backend = 'bokeh'
        self.default_comm = bokeh_renderer.comms['default']

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))
Exemple #10
0
 def test_graph_op_edge_color_linear(self):
     edges = [(0, 1, 2), (0, 2, 0.5), (1, 3, 3)]
     graph = Graph(edges, vdims='color').options(edge_color='color')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_array(), np.array([2, 0.5, 3]))
     self.assertEqual(edges.get_clim(), (0.5, 3))
    def setUp(self):
        if not mpl_renderer:
            raise SkipTest(
                'Matplotlib tests require matplotlib to be available')
        self.previous_backend = Store.current_backend
        Store.current_backend = 'matplotlib'
        self.default_comm = mpl_renderer.comms['default']
        mpl_renderer.comms['default'] = (comms.Comm, '')

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target), ))
        self.node_info = Dataset(['Output'] + ['Input'] * (N - 1),
                                 vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))
Exemple #12
0
 def test_graph_op_node_color_categorical(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 'A'), (0, 1, 1, 'B'), (1, 1, 2, 'A')],
                   vdims='color')
     graph = Graph((edges, nodes)).options(node_color='color')
     plot = mpl_renderer.get_plot(graph)
     artist = plot.handles['nodes']
     self.assertEqual(np.asarray(artist.get_array()), np.array([0, 1, 0]))
Exemple #13
0
 def test_graph_op_edge_color_update(self):
     graph = HoloMap({
         0: Graph([(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')],
                 vdims='color'),
         1: Graph([(0, 1, 'green'), (0, 2, 'blue'), (1, 3, 'red')],
                  vdims='color')}).options(edge_color='color')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_edgecolors(), np.array([
         [1. , 0. , 0. , 1. ], [0. , 0.50196078, 0. , 1. ],
         [0. , 0. , 1. , 1. ]]
     ))
     plot.update((1,))
     self.assertEqual(edges.get_edgecolors(), np.array([
         [0. , 0.50196078, 0. , 1. ], [0. , 0. , 1. , 1. ],
         [1. , 0. , 0. , 1. ]]
     ))
Exemple #14
0
 def get_graph(i):
     c1, c2, c3 = {
         0: ('#00FF00', '#0000FF', '#FF0000'),
         1: ('#FF0000', '#00FF00', '#0000FF')
     }[i]
     nodes = Nodes([(0, 0, 0, c1), (0, 1, 1, c2), (1, 1, 2, c3)],
                   vdims='color')
     return Graph((edges, nodes))
Exemple #15
0
 def test_graph_op_edge_line_width(self):
     edges = [(0, 1, 2), (0, 2, 10), (1, 3, 6)]
     graph = Graph(edges, vdims='line_width').options(edge_line_width='line_width')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['multi_line_1_source']
     glyph = plot.handles['multi_line_1_glyph']
     self.assertEqual(glyph.line_width, {'field': 'edge_line_width'})
     self.assertEqual(cds.data['edge_line_width'], np.array([2, 10, 6]))
Exemple #16
0
 def test_graph_op_edge_alpha(self):
     edges = [(0, 1, 0.1), (0, 2, 0.5), (1, 3, 0.3)]
     graph = Graph(edges, vdims='alpha').options(edge_alpha='alpha')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['multi_line_1_source']
     glyph = plot.handles['multi_line_1_glyph']
     self.assertEqual(glyph.line_alpha, {'field': 'edge_alpha'})
     self.assertEqual(cds.data['edge_alpha'], np.array([0.1, 0.5, 0.3]))
Exemple #17
0
 def test_graph_op_edge_color(self):
     edges = [(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')]
     graph = Graph(edges, vdims='color').options(edge_color='color')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['multi_line_1_source']
     glyph = plot.handles['multi_line_1_glyph']
     self.assertEqual(glyph.line_color, {'field': 'edge_color'})
     self.assertEqual(cds.data['edge_color'], np.array(['red', 'green', 'blue']))
Exemple #18
0
 def test_graph_op_edge_color(self):
     edges = [(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')]
     graph = Graph(edges, vdims='color').options(edge_color='color')
     plot = mpl_renderer.get_plot(graph)
     edges = plot.handles['edges']
     self.assertEqual(edges.get_edgecolors(), np.array([
         [1. , 0. , 0. , 1. ], [0. , 0.50196078, 0. , 1. ],
         [0. , 0. , 1. , 1. ]]
     ))
Exemple #19
0
 def test_graph_op_edge_color_categorical(self):
     edges = [(0, 1, 'C'), (0, 2, 'B'), (1, 3, 'A')]
     graph = Graph(edges, vdims='color').options(edge_color='color')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['multi_line_1_source']
     glyph = plot.handles['multi_line_1_glyph']
     cmapper = plot.handles['edge_color_color_mapper']
     self.assertEqual(glyph.line_color, {'field': 'edge_color', 'transform': cmapper})
     self.assertEqual(cds.data['edge_color'], np.array(['C', 'B', 'A']))
Exemple #20
0
 def test_graph_op_node_line_width(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 6)], vdims='line_width')
     graph = Graph((edges, nodes)).options(node_line_width='line_width')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['scatter_1_source']
     glyph = plot.handles['scatter_1_glyph']
     self.assertEqual(glyph.line_width, {'field': 'node_line_width'})
     self.assertEqual(cds.data['node_line_width'], np.array([2, 4, 6]))
Exemple #21
0
 def test_graph_op_node_color(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, '#000000'), (0, 1, 1, '#FF0000'), (1, 1, 2, '#00FF00')],
                   vdims='color')
     graph = Graph((edges, nodes)).options(node_color='color')
     plot = mpl_renderer.get_plot(graph)
     artist = plot.handles['nodes']
     self.assertEqual(artist.get_facecolors(),
                      np.array([[0, 0, 0, 1], [1, 0, 0, 1], [0, 1, 0, 1]]))
Exemple #22
0
 def test_graph_op_node_color_linear(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 0.5), (0, 1, 1, 1.5), (1, 1, 2, 2.5)],
                   vdims='color')
     graph = Graph((edges, nodes)).options(node_color='color')
     plot = mpl_renderer.get_plot(graph)
     artist = plot.handles['nodes']
     self.assertEqual(np.asarray(artist.get_array()), np.array([0.5, 1.5, 2.5]))
     self.assertEqual(artist.get_clim(), (0.5, 2.5))
Exemple #23
0
 def test_graph_op_node_alpha(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 0.2), (0, 1, 1, 0.6), (1, 1, 2, 1)], vdims='alpha')
     graph = Graph((edges, nodes)).options(node_alpha='alpha')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['scatter_1_source']
     glyph = plot.handles['scatter_1_glyph']
     self.assertEqual(glyph.fill_alpha, {'field': 'node_alpha'})
     self.assertEqual(glyph.line_alpha, {'field': 'node_alpha'})
     self.assertEqual(cds.data['node_alpha'], np.array([0.2, 0.6, 1]))
Exemple #24
0
 def test_graph_op_node_color(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 'red'), (0, 1, 1, 'green'), (1, 1, 2, 'blue')],
                   vdims='color')
     graph = Graph((edges, nodes)).options(node_color='color')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['scatter_1_source']
     glyph = plot.handles['scatter_1_glyph']
     self.assertEqual(glyph.fill_color, {'field': 'node_color'})
     self.assertEqual(glyph.line_color, 'black')
     self.assertEqual(cds.data['node_color'], np.array(['red', 'green', 'blue']))
Exemple #25
0
 def test_graph_op_node_color_categorical(self):
     edges = [(0, 1), (0, 2)]
     nodes = Nodes([(0, 0, 0, 'A'), (0, 1, 1, 'B'), (1, 1, 2, 'C')],
                   vdims='color')
     graph = Graph((edges, nodes)).options(node_color='color')
     plot = bokeh_renderer.get_plot(graph)
     cds = plot.handles['scatter_1_source']
     glyph = plot.handles['scatter_1_glyph']
     cmapper = plot.handles['node_color_color_mapper']
     self.assertEqual(glyph.fill_color, {'field': 'node_color', 'transform': cmapper})
     self.assertEqual(glyph.line_color, 'black')
     self.assertEqual(cds.data['node_color'], np.array(['A', 'B', 'C']))
Exemple #26
0
    def setUp(self):
        super(TestBokehGraphPlot, self).setUp()

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights),), vdims='Weight')
Exemple #27
0
    def setUp(self):
        if not mpl_renderer:
            raise SkipTest('Matplotlib tests require matplotlib to be available')
        self.previous_backend = Store.current_backend
        Store.current_backend = 'matplotlib'
        self.default_comm = mpl_renderer.comms['default']
        mpl_renderer.comms['default'] = (comms.Comm, '')

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))
Exemple #28
0
    def test_graph_op_node_alpha(self):
        import matplotlib as mpl
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 0.2), (0, 1, 1, 0.6), (1, 1, 2, 1)],
                      vdims='alpha')
        graph = Graph((edges, nodes)).options(node_alpha='alpha')

        if LooseVersion(mpl.__version__) < LooseVersion("3.4.0"):
            # Python 3.6 only support up to matplotlib 3.3
            with self.assertRaises(Exception):
                mpl_renderer.get_plot(graph)
        else:
            plot = mpl_renderer.get_plot(graph)
            artist = plot.handles['nodes']
            self.assertEqual(artist.get_alpha(), np.array([0.2, 0.6, 1]))
Exemple #29
0
    def setUp(self):
        if not bokeh_renderer:
            raise SkipTest("Bokeh required to test plot instantiation")
        self.previous_backend = Store.current_backend
        Store.current_backend = 'bokeh'
        self.default_comm = bokeh_renderer.comms['default']

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target), ))
        self.node_info = Dataset(['Output'] + ['Input'] * (N - 1),
                                 vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights), ),
                            vdims='Weight')
class MplGraphPlotTests(ComparisonTestCase):
    def setUp(self):
        if not mpl_renderer:
            raise SkipTest(
                'Matplotlib tests require matplotlib to be available')
        self.previous_backend = Store.current_backend
        Store.current_backend = 'matplotlib'
        self.default_comm = mpl_renderer.comms['default']
        mpl_renderer.comms['default'] = (comms.Comm, '')

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target), ))
        self.node_info = Dataset(['Output'] + ['Input'] * (N - 1),
                                 vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))

    def tearDown(self):
        mpl_renderer.comms['default'] = self.default_comm
        Store.current_backend = self.previous_backend

    def test_plot_simple_graph(self):
        plot = mpl_renderer.get_plot(self.graph)
        nodes = plot.handles['nodes']
        edges = plot.handles['edges']
        self.assertEqual(nodes.get_offsets(), self.graph.nodes.array([0, 1]))
        self.assertEqual([p.vertices for p in edges.get_paths()],
                         [p.array() for p in self.graph.edgepaths.split()])

    def test_plot_graph_colored_nodes(self):
        g = self.graph2.opts(plot=dict(color_index='Label'),
                             style=dict(cmap='Set1'))
        plot = mpl_renderer.get_plot(g)
        nodes = plot.handles['nodes']
        edges = plot.handles['edges']
        self.assertEqual(nodes.get_offsets(), self.graph.nodes.array([0, 1]))
        self.assertEqual([p.vertices for p in edges.get_paths()],
                         [p.array() for p in self.graph.edgepaths.split()])
        self.assertEqual(nodes.get_array(), np.array([1, 0, 0, 0, 0, 0, 0, 0]))
Exemple #31
0
class MplGraphPlotTests(ComparisonTestCase):

    def setUp(self):
        if not mpl_renderer:
            raise SkipTest('Matplotlib tests require matplotlib to be available')
        self.previous_backend = Store.current_backend
        Store.current_backend = 'matplotlib'
        self.default_comm = mpl_renderer.comms['default']
        mpl_renderer.comms['default'] = (comms.Comm, '')

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))

    def tearDown(self):
        mpl_renderer.comms['default'] = self.default_comm
        Store.current_backend = self.previous_backend

    def test_plot_simple_graph(self):
        plot = mpl_renderer.get_plot(self.graph)
        nodes = plot.handles['nodes']
        edges = plot.handles['edges']
        self.assertEqual(nodes.get_offsets(), self.graph.nodes.array([0, 1]))
        self.assertEqual([p.vertices for p in edges.get_paths()],
                         [p.array() for p in self.graph.edgepaths.split()])

    def test_plot_graph_colored_nodes(self):
        g = self.graph2.opts(plot=dict(color_index='Label'), style=dict(cmap='Set1'))
        plot = mpl_renderer.get_plot(g)
        nodes = plot.handles['nodes']
        edges = plot.handles['edges']
        self.assertEqual(nodes.get_offsets(), self.graph.nodes.array([0, 1]))
        self.assertEqual([p.vertices for p in edges.get_paths()],
                         [p.array() for p in self.graph.edgepaths.split()])
        self.assertEqual(nodes.get_array(), np.array([1, 0, 0, 0, 0, 0, 0, 0]))
Exemple #32
0
class TestBokehGraphPlot(TestBokehPlot):
    def setUp(self):
        super(TestBokehGraphPlot, self).setUp()

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target), ))
        self.node_info = Dataset(['Output'] + ['Input'] * (N - 1),
                                 vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights), ),
                            vdims='Weight')

    def test_plot_simple_graph(self):
        plot = bokeh_renderer.get_plot(self.graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        layout = {str(int(z)): (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_plot_graph_with_paths(self):
        graph = self.graph.clone(
            (self.graph.data, self.graph.nodes, self.graph.edgepaths))
        plot = bokeh_renderer.get_plot(graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        edges = graph.edgepaths.split()
        self.assertEqual(edge_source.data['xs'],
                         [path.dimension_values(0) for path in edges])
        self.assertEqual(edge_source.data['ys'],
                         [path.dimension_values(1) for path in edges])
        layout = {str(int(z)): (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_graph_inspection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, NodesAndLinkedEdges)
        self.assertEqual(hover.tooltips, [('index', '@{index_hover}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges(self):
        plot = bokeh_renderer.get_plot(
            self.graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('start', '@{start_values}'),
                                          ('end', '@{end_values}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges_non_default_names(self):
        graph = self.graph.redim(start='source', end='target')
        plot = bokeh_renderer.get_plot(
            graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('source', '@{source}'),
                                          ('target', '@{target}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_none(self):
        plot = bokeh_renderer.get_plot(
            self.graph.opts(plot=dict(inspection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        self.assertIs(renderer.inspection_policy, None)

    def test_graph_selection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, NodesAndLinkedEdges)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_edges(self):
        plot = bokeh_renderer.get_plot(
            self.graph.opts(plot=dict(selection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, EdgesAndLinkedNodes)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_none(self):
        plot = bokeh_renderer.get_plot(
            self.graph.opts(plot=dict(selection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        self.assertIs(renderer.selection_policy, None)

    def test_graph_nodes_categorical_colormapped(self):
        g = self.graph2.opts(plot=dict(color_index='Label'),
                             style=dict(cmap='Set1'))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['color_mapper']
        node_source = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['Output', 'Input'])
        self.assertEqual(node_source.data['Label'], self.node_info['Label'])
        self.assertEqual(glyph.fill_color, {
            'field': 'Label',
            'transform': cmapper
        })

    def test_graph_nodes_numerically_colormapped(self):
        g = self.graph3.opts(plot=dict(color_index='Weight'),
                             style=dict(cmap='viridis'))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['color_mapper']
        node_source = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertIsInstance(cmapper, LinearColorMapper)
        self.assertEqual(cmapper.low, self.weights.min())
        self.assertEqual(cmapper.high, self.weights.max())
        self.assertEqual(node_source.data['Weight'], self.node_info2['Weight'])
        self.assertEqual(glyph.fill_color, {
            'field': 'Weight',
            'transform': cmapper
        })

    def test_graph_edges_categorical_colormapped(self):
        raise SkipTest(
            'Temporarily disabled until array interface is simplified.')

        g = self.graph3.opts(plot=dict(edge_color_index='start'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['edge_colormapper']
        edge_source = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        factors = ['0', '1', '2', '3', '4', '5', '6', '7']
        self.assertEqual(cmapper.factors, factors)
        self.assertEqual(edge_source.data['start_str'], factors)
        self.assertEqual(glyph.line_color, {
            'field': 'start_str',
            'transform': cmapper
        })

    def test_graph_edges_numerically_colormapped(self):
        g = self.graph4.opts(plot=dict(edge_color_index='Weight'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['edge_colormapper']
        edge_source = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertIsInstance(cmapper, LinearColorMapper)
        self.assertEqual(cmapper.low, self.weights.min())
        self.assertEqual(cmapper.high, self.weights.max())
        self.assertEqual(edge_source.data['Weight'], self.node_info2['Weight'])
        self.assertEqual(glyph.line_color, {
            'field': 'Weight',
            'transform': cmapper
        })
Exemple #33
0
class TestMplGraphPlot(TestMPLPlot):

    def setUp(self):
        super(TestMplGraphPlot, self).setUp()

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights),), vdims='Weight')

    def test_plot_simple_graph(self):
        plot = mpl_renderer.get_plot(self.graph)
        nodes = plot.handles['nodes']
        edges = plot.handles['edges']
        self.assertEqual(nodes.get_offsets(), self.graph.nodes.array([0, 1]))
        self.assertEqual([p.vertices for p in edges.get_paths()],
                         [p.array() for p in self.graph.edgepaths.split()])

    def test_plot_graph_categorical_colored_nodes(self):
        g = self.graph2.opts(plot=dict(color_index='Label'), style=dict(cmap='Set1'))
        plot = mpl_renderer.get_plot(g)
        nodes = plot.handles['nodes']
        facecolors = np.array([[0.89411765, 0.10196078, 0.10980392, 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.],
                               [0.6       , 0.6       , 0.6       , 1.]])
        self.assertEqual(nodes.get_facecolors(), facecolors)

    def test_plot_graph_numerically_colored_nodes(self):
        g = self.graph3.opts(plot=dict(color_index='Weight'), style=dict(cmap='viridis'))
        plot = mpl_renderer.get_plot(g)
        nodes = plot.handles['nodes']
        self.assertEqual(nodes.get_array(), self.weights)
        self.assertEqual(nodes.get_clim(), (self.weights.min(), self.weights.max()))

    def test_plot_graph_categorical_colored_edges(self):
        g = self.graph3.opts(plot=dict(edge_color_index='start'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = mpl_renderer.get_plot(g)
        edges = plot.handles['edges']
        colors = np.array([[1., 1., 1., 1.],
                           [0., 0., 0., 1.],
                           [1., 1., 1., 1.],
                           [0., 0., 0., 1.],
                           [1., 1., 1., 1.],
                           [0., 0., 0., 1.],
                           [1., 1., 1., 1.],
                           [0., 0., 0., 1.]])
        self.assertEqual(edges.get_colors(), colors)

    def test_plot_graph_numerically_colored_edges(self):
        g = self.graph4.opts(plot=dict(edge_color_index='Weight'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = mpl_renderer.get_plot(g)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_array(), self.weights)
        self.assertEqual(edges.get_clim(), (self.weights.min(), self.weights.max()))

    ###########################
    #    Styling mapping      #
    ###########################

    def test_graph_op_node_color(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, '#000000'), (0, 1, 1, '#FF0000'), (1, 1, 2, '#00FF00')],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_facecolors(),
                         np.array([[0, 0, 0, 1], [1, 0, 0, 1], [0, 1, 0, 1]]))

    def test_graph_op_node_color_update(self):
        edges = [(0, 1), (0, 2)]
        def get_graph(i):
            c1, c2, c3 = {0: ('#00FF00', '#0000FF', '#FF0000'),
                          1: ('#FF0000', '#00FF00', '#0000FF')}[i]
            nodes = Nodes([(0, 0, 0, c1), (0, 1, 1, c2), (1, 1, 2, c3)],
                      vdims='color')
            return Graph((edges, nodes))
        graph = HoloMap({0: get_graph(0), 1: get_graph(1)}).options(node_color='color')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_facecolors(),
                         np.array([[0, 1, 0, 1], [0, 0, 1, 1], [1, 0, 0, 1]]))
        plot.update((1,))
        self.assertEqual(artist.get_facecolors(),
                         np.array([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]]))

    def test_graph_op_node_color_linear(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 0.5), (0, 1, 1, 1.5), (1, 1, 2, 2.5)],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_array(), np.array([0.5, 1.5, 2.5]))
        self.assertEqual(artist.get_clim(), (0.5, 2.5))

    def test_graph_op_node_color_linear_update(self):
        edges = [(0, 1), (0, 2)]
        def get_graph(i):
            c1, c2, c3 = {0: (0.5, 1.5, 2.5),
                          1: (3, 2, 1)}[i]
            nodes = Nodes([(0, 0, 0, c1), (0, 1, 1, c2), (1, 1, 2, c3)],
                      vdims='color')
            return Graph((edges, nodes))
        graph = HoloMap({0: get_graph(0), 1: get_graph(1)}).options(node_color='color', framewise=True)
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_array(), np.array([0.5, 1.5, 2.5]))
        self.assertEqual(artist.get_clim(), (0.5, 2.5))
        plot.update((1,))
        self.assertEqual(artist.get_array(), np.array([3, 2, 1]))
        self.assertEqual(artist.get_clim(), (1, 3))

    def test_graph_op_node_color_categorical(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 'A'), (0, 1, 1, 'B'), (1, 1, 2, 'A')],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_array(), np.array([0, 1, 0]))

    def test_graph_op_node_size(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 6)],
                      vdims='size')
        graph = Graph((edges, nodes)).options(node_size='size')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_sizes(), np.array([4, 16, 36]))

    def test_graph_op_node_size_update(self):
        edges = [(0, 1), (0, 2)]
        def get_graph(i):
            c1, c2, c3 = {0: (2, 4, 6),
                          1: (12, 3, 5)}[i]
            nodes = Nodes([(0, 0, 0, c1), (0, 1, 1, c2), (1, 1, 2, c3)],
                      vdims='size')
            return Graph((edges, nodes))
        graph = HoloMap({0: get_graph(0), 1: get_graph(1)}).options(node_size='size')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_sizes(), np.array([4, 16, 36]))
        plot.update((1,))
        self.assertEqual(artist.get_sizes(), np.array([144, 9, 25]))

    def test_graph_op_node_linewidth(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 3.5)], vdims='line_width')
        graph = Graph((edges, nodes)).options(node_linewidth='line_width')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_linewidths(), [2, 4, 3.5])

    def test_graph_op_node_linewidth_update(self):
        edges = [(0, 1), (0, 2)]
        def get_graph(i):
            c1, c2, c3 = {0: (2, 4, 6),
                          1: (12, 3, 5)}[i]
            nodes = Nodes([(0, 0, 0, c1), (0, 1, 1, c2), (1, 1, 2, c3)],
                      vdims='line_width')
            return Graph((edges, nodes))
        graph = HoloMap({0: get_graph(0), 1: get_graph(1)}).options(node_linewidth='line_width')
        plot = mpl_renderer.get_plot(graph)
        artist = plot.handles['nodes']
        self.assertEqual(artist.get_linewidths(), [2, 4, 6])
        plot.update((1,))
        self.assertEqual(artist.get_linewidths(), [12, 3, 5])

    def test_graph_op_node_alpha(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 0.2), (0, 1, 1, 0.6), (1, 1, 2, 1)], vdims='alpha')
        graph = Graph((edges, nodes)).options(node_alpha='alpha')
        with self.assertRaises(Exception):
            mpl_renderer.get_plot(graph)

    def test_graph_op_edge_color(self):
        edges = [(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_edgecolors(), np.array([
            [1. , 0. , 0. , 1. ], [0. , 0.50196078, 0. , 1. ],
            [0. , 0. , 1. , 1. ]]
        ))

    def test_graph_op_edge_color_update(self):
        graph = HoloMap({
            0: Graph([(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')],
                    vdims='color'),
            1: Graph([(0, 1, 'green'), (0, 2, 'blue'), (1, 3, 'red')],
                     vdims='color')}).options(edge_color='color')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_edgecolors(), np.array([
            [1. , 0. , 0. , 1. ], [0. , 0.50196078, 0. , 1. ],
            [0. , 0. , 1. , 1. ]]
        ))
        plot.update((1,))
        self.assertEqual(edges.get_edgecolors(), np.array([
            [0. , 0.50196078, 0. , 1. ], [0. , 0. , 1. , 1. ],
            [1. , 0. , 0. , 1. ]]
        ))

    def test_graph_op_edge_color_linear(self):
        edges = [(0, 1, 2), (0, 2, 0.5), (1, 3, 3)]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_array(), np.array([2, 0.5, 3]))
        self.assertEqual(edges.get_clim(), (0.5, 3))

    def test_graph_op_edge_color_linear_update(self):
        graph = HoloMap({
            0: Graph([(0, 1, 2), (0, 2, 0.5), (1, 3, 3)],
                    vdims='color'),
            1: Graph([(0, 1, 4.3), (0, 2, 1.4), (1, 3, 2.6)],
                     vdims='color')}).options(edge_color='color', framewise=True)
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_array(), np.array([2, 0.5, 3]))
        self.assertEqual(edges.get_clim(), (0.5, 3))
        plot.update((1,))
        self.assertEqual(edges.get_array(), np.array([4.3, 1.4, 2.6]))
        self.assertEqual(edges.get_clim(), (1.4, 4.3))

    def test_graph_op_edge_color_categorical(self):
        edges = [(0, 1, 'C'), (0, 2, 'B'), (1, 3, 'A')]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_array(), np.array([0, 1, 2]))
        self.assertEqual(edges.get_clim(), (0, 2))

    def test_graph_op_edge_alpha(self):
        edges = [(0, 1, 0.1), (0, 2, 0.5), (1, 3, 0.3)]
        graph = Graph(edges, vdims='alpha').options(edge_alpha='alpha')
        with self.assertRaises(Exception):
            mpl_renderer.get_plot(graph)

    def test_graph_op_edge_linewidth(self):
        edges = [(0, 1, 2), (0, 2, 10), (1, 3, 6)]
        graph = Graph(edges, vdims='line_width').options(edge_linewidth='line_width')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_linewidths(), [2, 10, 6])

    def test_graph_op_edge_line_width_update(self):
        graph = HoloMap({
            0: Graph([(0, 1, 2), (0, 2, 0.5), (1, 3, 3)],
                    vdims='line_width'),
            1: Graph([(0, 1, 4.3), (0, 2, 1.4), (1, 3, 2.6)],
                     vdims='line_width')}).options(edge_linewidth='line_width')
        plot = mpl_renderer.get_plot(graph)
        edges = plot.handles['edges']
        self.assertEqual(edges.get_linewidths(), [2, 0.5, 3])
        plot.update((1,))
        self.assertEqual(edges.get_linewidths(), [4.3, 1.4, 2.6])
Exemple #34
0
class TestBokehGraphPlot(TestBokehPlot):

    def setUp(self):
        super(TestBokehGraphPlot, self).setUp()

        N = 8
        self.nodes = circular_layout(np.arange(N, dtype=np.int32))
        self.source = np.arange(N, dtype=np.int32)
        self.target = np.zeros(N, dtype=np.int32)
        self.weights = np.random.rand(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.node_info2 = Dataset(self.weights, vdims='Weight')
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        self.graph3 = Graph(((self.source, self.target), self.node_info2))
        self.graph4 = Graph(((self.source, self.target, self.weights),), vdims='Weight')

    def test_plot_simple_graph(self):
        plot = bokeh_renderer.get_plot(self.graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        layout = {str(int(z)): (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_plot_graph_with_paths(self):
        graph = self.graph.clone((self.graph.data, self.graph.nodes, self.graph.edgepaths))
        plot = bokeh_renderer.get_plot(graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        edges = graph.edgepaths.split()
        self.assertEqual(edge_source.data['xs'], [path.dimension_values(0) for path in edges])
        self.assertEqual(edge_source.data['ys'], [path.dimension_values(1) for path in edges])
        layout = {str(int(z)): (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_graph_inspection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, NodesAndLinkedEdges)
        self.assertEqual(hover.tooltips, [('index', '@{index_hover}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('start', '@{start_values}'), ('end', '@{end_values}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges_non_default_names(self):
        graph = self.graph.redim(start='source', end='target')
        plot = bokeh_renderer.get_plot(graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('source', '@{source}'), ('target', '@{target}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_none(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(inspection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        self.assertIs(renderer.inspection_policy, None)

    def test_graph_selection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, NodesAndLinkedEdges)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_edges(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(selection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, EdgesAndLinkedNodes)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_none(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(selection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        self.assertIs(renderer.selection_policy, None)

    def test_graph_nodes_categorical_colormapped(self):
        g = self.graph2.opts(plot=dict(color_index='Label'), style=dict(cmap='Set1'))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['color_mapper']
        node_source = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['Output', 'Input'])
        self.assertEqual(node_source.data['Label'], self.node_info['Label'])
        self.assertEqual(glyph.fill_color, {'field': 'Label', 'transform': cmapper})

    def test_graph_nodes_numerically_colormapped(self):
        g = self.graph3.opts(plot=dict(color_index='Weight'), style=dict(cmap='viridis'))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['color_mapper']
        node_source = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertIsInstance(cmapper, LinearColorMapper)
        self.assertEqual(cmapper.low, self.weights.min())
        self.assertEqual(cmapper.high, self.weights.max())
        self.assertEqual(node_source.data['Weight'], self.node_info2['Weight'])
        self.assertEqual(glyph.fill_color, {'field': 'Weight', 'transform': cmapper})

    def test_graph_edges_categorical_colormapped(self):
        g = self.graph3.opts(plot=dict(edge_color_index='start'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['edge_colormapper']
        edge_source = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        factors = ['0', '1', '2', '3', '4', '5', '6', '7']
        self.assertEqual(cmapper.factors, factors)
        self.assertEqual(edge_source.data['start_str__'], factors)
        self.assertEqual(glyph.line_color, {'field': 'start_str__', 'transform': cmapper})

    def test_graph_edges_numerically_colormapped(self):
        g = self.graph4.opts(plot=dict(edge_color_index='Weight'),
                             style=dict(edge_cmap=['#FFFFFF', '#000000']))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['edge_colormapper']
        edge_source = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertIsInstance(cmapper, LinearColorMapper)
        self.assertEqual(cmapper.low, self.weights.min())
        self.assertEqual(cmapper.high, self.weights.max())
        self.assertEqual(edge_source.data['Weight'], self.node_info2['Weight'])
        self.assertEqual(glyph.line_color, {'field': 'Weight', 'transform': cmapper})

    ###########################
    #    Styling mapping      #
    ###########################

    def test_graph_op_node_color(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 'red'), (0, 1, 1, 'green'), (1, 1, 2, 'blue')],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertEqual(glyph.fill_color, {'field': 'node_color'})
        self.assertEqual(glyph.line_color, 'black')
        self.assertEqual(cds.data['node_color'], np.array(['red', 'green', 'blue']))

    def test_graph_op_node_color_linear(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 0.5), (0, 1, 1, 1.5), (1, 1, 2, 2.5)],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        cmapper = plot.handles['node_color_color_mapper']
        self.assertEqual(glyph.fill_color, {'field': 'node_color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, 'black')
        self.assertEqual(cds.data['node_color'], np.array([0.5, 1.5, 2.5]))

    def test_graph_op_node_color_categorical(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 'A'), (0, 1, 1, 'B'), (1, 1, 2, 'C')],
                      vdims='color')
        graph = Graph((edges, nodes)).options(node_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        cmapper = plot.handles['node_color_color_mapper']
        self.assertEqual(glyph.fill_color, {'field': 'node_color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, 'black')
        self.assertEqual(cds.data['node_color'], np.array(['A', 'B', 'C']))

    def test_graph_op_node_size(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 6)],
                      vdims='size')
        graph = Graph((edges, nodes)).options(node_size='size')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertEqual(glyph.size, {'field': 'node_size'})
        self.assertEqual(cds.data['node_size'], np.array([2, 4, 6]))

    def test_graph_op_node_alpha(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 0.2), (0, 1, 1, 0.6), (1, 1, 2, 1)], vdims='alpha')
        graph = Graph((edges, nodes)).options(node_alpha='alpha')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertEqual(glyph.fill_alpha, {'field': 'node_alpha'})
        self.assertEqual(glyph.line_alpha, {'field': 'node_alpha'})
        self.assertEqual(cds.data['node_alpha'], np.array([0.2, 0.6, 1]))

    def test_graph_op_node_line_width(self):
        edges = [(0, 1), (0, 2)]
        nodes = Nodes([(0, 0, 0, 2), (0, 1, 1, 4), (1, 1, 2, 6)], vdims='line_width')
        graph = Graph((edges, nodes)).options(node_line_width='line_width')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertEqual(glyph.line_width, {'field': 'node_line_width'})
        self.assertEqual(cds.data['node_line_width'], np.array([2, 4, 6]))

    def test_graph_op_edge_color(self):
        edges = [(0, 1, 'red'), (0, 2, 'green'), (1, 3, 'blue')]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertEqual(glyph.line_color, {'field': 'edge_color'})
        self.assertEqual(cds.data['edge_color'], np.array(['red', 'green', 'blue']))

    def test_graph_op_edge_color_linear(self):
        edges = [(0, 1, 2), (0, 2, 0.5), (1, 3, 3)]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        cmapper = plot.handles['edge_color_color_mapper']
        self.assertEqual(glyph.line_color, {'field': 'edge_color', 'transform': cmapper})
        self.assertEqual(cds.data['edge_color'], np.array([2, 0.5, 3]))

    def test_graph_op_edge_color_categorical(self):
        edges = [(0, 1, 'C'), (0, 2, 'B'), (1, 3, 'A')]
        graph = Graph(edges, vdims='color').options(edge_color='color')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        cmapper = plot.handles['edge_color_color_mapper']
        self.assertEqual(glyph.line_color, {'field': 'edge_color', 'transform': cmapper})
        self.assertEqual(cds.data['edge_color'], np.array(['C', 'B', 'A']))

    def test_graph_op_edge_alpha(self):
        edges = [(0, 1, 0.1), (0, 2, 0.5), (1, 3, 0.3)]
        graph = Graph(edges, vdims='alpha').options(edge_alpha='alpha')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertEqual(glyph.line_alpha, {'field': 'edge_alpha'})
        self.assertEqual(cds.data['edge_alpha'], np.array([0.1, 0.5, 0.3]))

    def test_graph_op_edge_line_width(self):
        edges = [(0, 1, 2), (0, 2, 10), (1, 3, 6)]
        graph = Graph(edges, vdims='line_width').options(edge_line_width='line_width')
        plot = bokeh_renderer.get_plot(graph)
        cds = plot.handles['multi_line_1_source']
        glyph = plot.handles['multi_line_1_glyph']
        self.assertEqual(glyph.line_width, {'field': 'edge_line_width'})
        self.assertEqual(cds.data['edge_line_width'], np.array([2, 10, 6]))
class BokehGraphPlotTests(ComparisonTestCase):

    
    def setUp(self):
        if not bokeh_renderer:
            raise SkipTest("Bokeh required to test plot instantiation")
        elif bokeh_version < str('0.12.9'):
            raise SkipTest("Bokeh >= 0.12.9 required to test graphs")
        self.previous_backend = Store.current_backend
        Store.current_backend = 'bokeh'
        self.default_comm = bokeh_renderer.comms['default']

        N = 8
        self.nodes = circular_layout(np.arange(N))
        self.source = np.arange(N)
        self.target = np.zeros(N)
        self.graph = Graph(((self.source, self.target),))
        self.node_info = Dataset(['Output']+['Input']*(N-1), vdims=['Label'])
        self.graph2 = Graph(((self.source, self.target), self.node_info))
        
    def tearDown(self):
        Store.current_backend = self.previous_backend
        bokeh_renderer.comms['default'] = self.default_comm
        
    def test_plot_simple_graph(self):
        plot = bokeh_renderer.get_plot(self.graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        layout = {z: (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_plot_graph_with_paths(self):
        graph = self.graph.clone((self.graph.data, self.graph.nodes, self.graph.edgepaths))
        plot = bokeh_renderer.get_plot(graph)
        node_source = plot.handles['scatter_1_source']
        edge_source = plot.handles['multi_line_1_source']
        layout_source = plot.handles['layout_source']
        self.assertEqual(node_source.data['index'], self.source)
        self.assertEqual(edge_source.data['start'], self.source)
        self.assertEqual(edge_source.data['end'], self.target)
        edges = graph.edgepaths.split()
        self.assertEqual(edge_source.data['xs'], [path.dimension_values(0) for path in edges])
        self.assertEqual(edge_source.data['ys'], [path.dimension_values(1) for path in edges])
        layout = {z: (x, y) for x, y, z in self.graph.nodes.array()}
        self.assertEqual(layout_source.graph_layout, layout)

    def test_graph_inspection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, NodesAndLinkedEdges)
        self.assertEqual(hover.tooltips, [('index', '@{index_hover}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('start', '@{start}'), ('end', '@{end}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_edges_non_default_names(self):
        graph = self.graph.redim(start='source', end='target')
        plot = bokeh_renderer.get_plot(graph.opts(plot=dict(inspection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.inspection_policy, EdgesAndLinkedNodes)
        self.assertEqual(hover.tooltips, [('source', '@{start}'), ('target', '@{end}')])
        self.assertIn(renderer, hover.renderers)

    def test_graph_inspection_policy_none(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(inspection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIs(renderer.inspection_policy, None)

    def test_graph_selection_policy_nodes(self):
        plot = bokeh_renderer.get_plot(self.graph)
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, NodesAndLinkedEdges)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_edges(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(selection_policy='edges')))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIsInstance(renderer.selection_policy, EdgesAndLinkedNodes)
        self.assertIn(renderer, hover.renderers)

    def test_graph_selection_policy_none(self):
        plot = bokeh_renderer.get_plot(self.graph.opts(plot=dict(selection_policy=None)))
        renderer = plot.handles['glyph_renderer']
        hover = plot.handles['hover']
        self.assertIs(renderer.selection_policy, None)

    def test_graph_nodes_colormapped(self):
        g = self.graph2.opts(plot=dict(color_index='Label'), style=dict(cmap='Set1'))
        plot = bokeh_renderer.get_plot(g)
        cmapper = plot.handles['color_mapper']
        node_source = plot.handles['scatter_1_source']
        glyph = plot.handles['scatter_1_glyph']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['Input', 'Output'])
        self.assertEqual(node_source.data['Label'], self.node_info['Label'])
        self.assertEqual(glyph.fill_color, {'field': 'Label', 'transform': cmapper})