感谢您提出这个问题。通过它,我意识到它目前的工作量超过了应有的工作量。我强烈建议您打开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.karate_club_graph()
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)
到目前为止,这都是相当正常的 Bokeh 图形布局代码。这是您需要为每个节点添加永久标签的附加部分:
from bokeh.transform import transform
# add the labels to the node renderer data source
source = r.node_renderer.data_source
source.data['names'] = [str(x*10) for x in source.data['index']]
# create a transform that can extract the actual x,y positions
code = """
var result = new Float64Array(xs.length)
for (var i = 0; i < xs.length; i++) {
result[i] = provider.graph_layout[xs[i]][%s]
}
return result
"""
xcoord = CustomJSTransform(v_func=code % "0", args=dict(provider=r.layout_provider))
ycoord = CustomJSTransform(v_func=code % "1", args=dict(provider=r.layout_provider))
# Use the transforms to supply coords to a LabelSet
labels = LabelSet(x=transform('index', xcoord),
y=transform('index', ycoord),
text='names', text_font_size="12px",
x_offset=5, y_offset=5,
source=source, render_mode='canvas')
p.add_layout(labels)
show(p)
基本上,由于 Bokeh(可能)在浏览器中计算布局,实际节点位置只能通过“布局提供程序”获得,目前访问起来有点乏味。正如我所说,请打开一个 GitHub 问题以建议为用户提供更好的服务。我们可以做一些非常快速和简单的事情来让用户更简单。
上面的代码导致: