如何在Bokeh中为NetworkX图添加边标签(交互式/永久)
嘿,我来帮你搞定在Bokeh里给NetworkX生成的图添加边标签的问题!不管你想要永久显示的固定标签,还是鼠标悬停才触发的交互式标签,这两种方案我都给你整理了可直接运行的代码示例,一步步来就行~
一、添加永久显示的边标签
永久标签会一直显示在边的中间位置,适合需要直观展示边信息(比如权重、关系类型)的场景。核心思路是先计算每条边的中点坐标,再用Bokeh的LabelSet来渲染标签:
import networkx as nx from bokeh.plotting import figure, show, from_networkx from bokeh.models import LabelSet, ColumnDataSource # 1. 先创建一个带边属性的NetworkX图 G = nx.Graph() G.add_edge("A", "B", weight=5, label="朋友") G.add_edge("B", "C", weight=2, label="同事") G.add_edge("C", "A", weight=8, label="家人") # 2. 把NetworkX图转换成Bokeh的图形对象 plot = figure(title="带永久边标签的NetworkX图", x_range=(-1.5, 1.5), y_range=(-1.5, 1.5)) graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0,0)) # 3. 计算每条边的中点坐标,准备标签数据 edge_data = [] for start, end, attrs in G.edges(data=True): # 获取两个节点的坐标 x_start, y_start = graph_renderer.layout_provider.graph_layout[start] x_end, y_end = graph_renderer.layout_provider.graph_layout[end] # 计算中点 x_mid = (x_start + x_end) / 2 y_mid = (y_start + y_end) / 2 edge_data.append({ "x": x_mid, "y": y_mid, "label": attrs["label"], # 这里用边的label属性,也可以换成weight "weight": attrs["weight"] }) # 4. 创建标签数据源和LabelSet source = ColumnDataSource(data=edge_data) labels = LabelSet(x="x", y="y", text="label", source=source, text_font_size="10pt", text_color="red") # 5. 把图形和标签添加到画布,显示 plot.renderers.append(graph_renderer) plot.add_layout(labels) show(plot)
二、添加交互式(鼠标悬停)边标签
如果不想让界面太拥挤,用鼠标悬停显示边信息会更清爽。这里要用到Bokeh的HoverTool,给边的渲染器绑定hover提示:
import networkx as nx from bokeh.plotting import figure, show, from_networkx from bokeh.models import HoverTool # 1. 同样先创建带边属性的NetworkX图 G = nx.Graph() G.add_edge("A", "B", weight=5, label="朋友") G.add_edge("B", "C", weight=2, label="同事") G.add_edge("C", "A", weight=8, label="家人") # 2. 转换为Bokeh图形对象 plot = figure(title="带交互式边标签的NetworkX图", x_range=(-1.5, 1.5), y_range=(-1.5, 1.5), tools="pan,wheel_zoom,reset") # 先加基础工具 graph_renderer = from_networkx(G, nx.spring_layout, scale=1, center=(0,0)) # 3. 给边的渲染器设置数据源,把边的属性传进去 graph_renderer.edge_renderer.data_source.data.update({ "labels": [attrs["label"] for _, _, attrs in G.edges(data=True)], "weights": [attrs["weight"] for _, _, attrs in G.edges(data=True)] }) # 4. 创建HoverTool,配置要显示的内容 hover = HoverTool(tooltips=[ ("关系类型", "@labels"), ("权重", "@weights") ], renderers=[graph_renderer.edge_renderer]) # 指定只对边生效 # 5. 添加hover工具到画布,显示图形 plot.add_tools(hover) plot.renderers.append(graph_renderer) show(plot)
小提示
- 如果你想自定义边的样式(比如颜色、粗细),可以直接修改
graph_renderer.edge_renderer.glyph的属性,比如graph_renderer.edge_renderer.glyph.line_width = 2 - 标签的内容可以灵活替换,比如用边的权重、自定义的关系ID等等,只要在NetworkX加边时传入对应的属性就行
内容的提问来源于stack exchange,提问作者Ly Harriet Bui
相关产品推荐
相关产品推荐

