Ly Harriet Bui
Ly Harriet Bui

Reputation: 49

How to add edge labels (interactive or permanent ones) for networkx graph in bokeh?

I would like to add label for edges in networkx graph using bokeh. How can I do this?

Upvotes: 0

Views: 2163

Answers (2)

bigreddot
bigreddot

Reputation: 34568

This question is similar to How to add permanent name labels (not interactive ones) on nodes for a networkx graph in bokeh? but different enough to warrant its own reply. As discussed in the other issue, this is currently a task that is probably harder than it should be to accomplish. I'd really encourage you to open a GitHub Issue to start a discussion of how this can be improved for users.

Here is complete example.

import networkx as nx

from bokeh.io import output_file, show
from bokeh.models import CustomJSTransform, LabelSet
from bokeh.models.graphs import from_networkx

from bokeh.plotting import figure

G=nx.barbell_graph(3,2)

p = figure(x_range=(-3,3), y_range=(-3,3))
p.grid.grid_line_color = None

r = from_networkx(G, nx.spring_layout, scale=3, center=(0,0))
r.node_renderer.glyph.size=15
r.edge_renderer.glyph.line_alpha=0.2

p.renderers.append(r)

This part is all fairly standard. To put labels on edges we must define transforms to extract the start and end coordinates from the layout provider. This code just averages the coordinates to put a label in the center of each edge (labelled by the start-end node numbers):

from bokeh.transform import transform

# add the labels to the edge renderer data source
source = r.edge_renderer.data_source
source.data['names'] = ["%d-%d" % (x, y) for (x,y) in zip(source.data['start'], source.data['end'])]

# create a transform that can extract and average the actual x,y positions
code = """
    const result = new Float64Array(xs.length)
    const coords = provider.get_edge_coordinates(source)[%s]
    for (let i = 0; i < xs.length; i++) {
        result[i] = (coords[i][0] + coords[i][1])/2
    }
    return result
"""
xcoord = CustomJSTransform(v_func=code % "0", args=dict(provider=r.layout_provider, source=source))
ycoord = CustomJSTransform(v_func=code % "1", args=dict(provider=r.layout_provider, source=source))

# Use the transforms to supply coords to a LabelSet
labels = LabelSet(x=transform('start', xcoord),
                  y=transform('start', ycoord),
                  text='names', text_font_size="12px",
                  x_offset=5, y_offset=5,
                  source=source, render_mode='canvas')

p.add_layout(labels)

show(p)

enter image description here


Edit 07/2022: Added missing var keyword to JavaScript part, would not show labels otherwise in current bokeh version.

Upvotes: 2

Dammio
Dammio

Reputation: 1059

I faced the same problem, I did check https://docs.bokeh.org/en/latest/docs/user_guide/styling.html and found it seems bokeh does not support well for the knowledge graph, including edge labels.

Upvotes: 0

Related Questions