将节点标签添加到散景网络图中

时间:2017-11-09 19:59:52

标签: python networkx bokeh

我使用以下代码生成交互式散景网络图。如何将节点名称添加到散景图中的节点?

from bokeh.io import show, output_notebook
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
from bokeh.models import LabelSet

plot = Plot(plot_width=900, plot_height=500,
            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.node_renderer.glyph.properties_with_values()
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)

show(plot)

生成的散景网络图: enter image description here

3 个答案:

答案 0 :(得分:9)

我猜你的意思是节点的交互式标签,我也想做。要实现这一目标,您需要修改几行:

hover = HoverTool(tooltips=[("Name:", "@name")])
plot.add_tools(hover, TapTool(), BoxSelectTool(), WheelZoomTool())
...
graph_renderer.inspection_policy = NodesAndLinkedEdges()

然后修改节点的数据源:

graph_renderer.node_renderer.data_source.data['name'] = [name1, ... ,nameN]

(数据源已经存在;它是一个字典,其中唯一的键是'index',一个编号的节点列表。因此,您可以添加更多引用相同长度列表的键 - 例如名称列表 - 这些列表可以通过'@key')

访问

答案 1 :(得分:1)

热门话题!!我想我得到了它。它们可能是更多的pythonic方式,但我做的是

  1. 使用相关标签创建数据源
  2. 使用pos = nx.circular_layout(G)
  3. 从图表中检索位置
  4. 将这些职位添加到我的数据源
  5. 从位置和来源
  6. 创建LabelSet 莱昂纳多,你错过了创造G的路线。我拿了karate_club_graph,这对我有用:

    from bokeh.models import ColumnDataSource
    pos = nx.circular_layout(G)
    x,y=zip(*pos.values())
    
    source = ColumnDataSource({'x':x,'y':y,'kid':['Joe %d' %ix for ix in range(len(x))]})
    labels = LabelSet(x='x', y='y', text='kid', source=source)
    
    plot.renderers.append(labels)
    

答案 2 :(得分:1)

我发现@ SergioLucero的答案太不完整而无法回答这个问题,代码示例无效。

但是,通过@ifearthenight创建的代码和答案(来自这个问题:Lining up labels with the nodes on a Bokeh figure generated from a NetworkX graph),我能够制作出一个有效的例子。

from bokeh.io import show, output_notebook
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, LabelSet
from bokeh.models.graphs import from_networkx
output_notebook()

G = nx.karate_club_graph()

plot = figure(title="Karate Club Graph", tools="", x_range=(-1.5, 1.5),
          y_range=(-1.5, 1.5), toolbar_location=None)
graph = from_networkx(G, nx.spring_layout)
plot.renderers.append(graph)

x, y = zip(*graph.layout_provider.graph_layout.values())
node_labels = nx.get_node_attributes(G, 'club')
source = ColumnDataSource({'x': x, 'y': y,
                           'club': [node_labels[i] for i in range(len(x))]})
labels = LabelSet(x='x', y='y', text='club', source=source,
                  background_fill_color='white')

plot.renderers.append(labels)
show(plot)