在bokeh中渲染后是否可以将边缘/节点信息返回给python?

时间:2019-04-15 22:23:29

标签: python-3.x bokeh networkx

我已使用此代码绘制网络图。 到目前为止,我已经看到了单击或悬停时更改图形属性的方法。 但是现在我想在单击时记录对象信息 例如:如果我单击一条边缘,我想将边缘细节返回到python进行处理。

import networkx as nx

from bokeh.io import show, output_file
from bokeh.models import Plot, Range1d, MultiLine, Circle, HoverTool, TapTool, BoxSelectTool
from bokeh.models.graphs import from_networkx, NodesAndLinkedEdges, EdgesAndLinkedNodes
from bokeh.palettes import Spectral4

G=nx.karate_club_graph()

plot = Plot(plot_width=400, plot_height=400,
            x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))
plot.title.text = "Graph Interaction Demonstration"

plot.add_tools(HoverTool(tooltips=None), TapTool(), BoxSelectTool())

graph_renderer = from_networkx(G, nx.circular_layout, scale=1, center=(0,0))

graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0])
graph_renderer.node_renderer.selection_glyph = Circle(size=15, fill_color=Spectral4[2])
graph_renderer.node_renderer.hover_glyph = Circle(size=15, fill_color=Spectral4[1])

graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=0.8, line_width=5)
graph_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=5)
graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5)

graph_renderer.selection_policy = NodesAndLinkedEdges()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()

plot.renderers.append(graph_renderer)

output_file("interactive_graphs.html")
show(plot)

1 个答案:

答案 0 :(得分:0)

此代码使用TapTool回调显示选定的索引以及选定边缘的开始/结束节点(轻按节点以首先进行选择)。代码适用于Bokeh v1.1.0

import networkx as nx

from bokeh.io import show, output_file
from bokeh.models import Plot, Range1d, MultiLine, Circle, HoverTool, TapTool, BoxSelectTool, CustomJS, Column, TextInput
from bokeh.models.graphs import from_networkx, NodesAndLinkedEdges, EdgesAndLinkedNodes
from bokeh.palettes import Spectral4
from bokeh.models.widgets.inputs import TextInput

G = nx.karate_club_graph()

plot = Plot(plot_width = 400, plot_height = 400,
            x_range = Range1d(-1.1, 1.1), y_range = Range1d(-1.1, 1.1))
plot.title.text = "Graph Interaction Demonstration"

plot.add_tools(HoverTool(tooltips = [('index', '$index'), ('start', '@start'), ('end', '@end')]), TapTool(), BoxSelectTool())

graph_renderer = from_networkx(G, nx.circular_layout, scale = 1, center = (0, 0))

graph_renderer.node_renderer.glyph = Circle(size = 15, fill_color = Spectral4[0])
graph_renderer.node_renderer.selection_glyph = Circle(size = 15, fill_color = Spectral4[2])
graph_renderer.node_renderer.hover_glyph = Circle(size = 15, fill_color = Spectral4[1])

graph_renderer.edge_renderer.glyph = MultiLine(line_color = "#CCCCCC", line_alpha = 0.8, line_width = 5)
graph_renderer.edge_renderer.selection_glyph = MultiLine(line_color = Spectral4[2], line_width = 5)
graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color = Spectral4[1], line_width = 5)

graph_renderer.selection_policy = NodesAndLinkedEdges()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()

plot.renderers.append(graph_renderer)

info_indices = TextInput(title = 'Selected indices:', value = '')
info_start_end = TextInput(title = 'Start => End Values:', value = '')
esource = graph_renderer.edge_renderer.data_source
code = """  info_indices.value = String(esource.selected.indices);
            start_end_values = []
            for(idx in esource.selected.indices)
            {
                index = esource.selected.indices[idx]
                start_end_values.push(esource.data['start'][index] + '=>' + esource.data['end'][index] )
            }
            info_start_end.value = String(start_end_values); """

callback = CustomJS(args = dict(esource = esource, 
                                info_indices = info_indices, 
                                info_start_end = info_start_end), 
                    code = code)
plot.select_one(TapTool).callback = callback

show(Column(plot, info_start_end))

结果:

enter image description here