I am using the following code to produce an interactive bokeh network graph. How do I add the name of the nodes to the nodes in the bokeh plot?
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)
resulting bokeh networkx graph:
I found @SergioLucero's answer too incomplete to answer the question, the code sample is not working.
However, with code and answer created by @ifearthenight (from this question: Lining up labels with the nodes on a Bokeh figure generated from a NetworkX graph) I was able to produce a working example.
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)
I guess you mean interactive labels for the nodes, something I also wanted to do. To achieve this, you need to modify a couple of lines:
hover = HoverTool(tooltips=[("Name:", "@name")])
plot.add_tools(hover, TapTool(), BoxSelectTool(), WheelZoomTool())
...
graph_renderer.inspection_policy = NodesAndLinkedEdges()
Then modify the data source for the nodes:
graph_renderer.node_renderer.data_source.data['name'] = [name1, ... ,nameN]
(the data source already exists; it's a dictionary for which the only key is 'index', a numbered list of nodes. Thus you can add more keys that reference lists of the same length - such as a list of names - and these lists can be accessed via '@key')
Hot topic!! I think I just got it. They may be more pythonic ways, but what I did was
Leonardo, you are missing the line where G gets created. I took the karate_club_graph and this works for me:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With