Как добавить метки ребер (интерактивные или постоянные) для графа networkx в боке? - PullRequest
0 голосов
/ 27 апреля 2018

Я хотел бы добавить метку для ребер в графе networkx, используя bokeh Как я могу это сделать?

1 Ответ

0 голосов
/ 27 апреля 2018

Этот вопрос похож на Как добавить постоянные имена (не интерактивные) на узлы для графа networkx в боке? , но достаточно разные, чтобы оправдать свой собственный ответ. Как обсуждалось в другой проблеме, в настоящее время эта задача, вероятно, сложнее, чем должна быть выполнена. Я действительно рекомендую вам открыть GitHub Issue , чтобы начать обсуждение того, как это можно улучшить для пользователей.

Вот полный пример.

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.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)

Эта часть довольно стандартная. Чтобы поместить метки на ребра, мы должны определить преобразования, чтобы извлечь начальную и конечную координаты из провайдера макета. Этот код просто усредняет координаты, чтобы поместить метку в центр каждого ребра (помеченную start-end номерами узлов):

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 = """
    var result = new Float64Array(xs.length)
    coords = provider.get_edge_coordinates(source)[%s]
    for (var 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

...