You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Bokeh绘制网络图时StaticLayoutProvider验证失败求助

问题

参考示例绘制网络图时,运行代码出现类型验证错误,具体代码如下:

data = {
    'source': ['A', 'C', 'B', 'F', 'G'],
    'target': ['B', 'D', 'E', 'C', 'E'],
    'weight': [5, 3, 10, 4, 7]
}
df = pd.DataFrame(data=data)
G = networkx.from_pandas_edgelist(df, 'source', 'target', 'weight')
# Choose a title!
title = 'Graph Network'

# Establish which categories will appear when hovering over each node
HOVER_TOOLTIPS = [("Character", "@index")]
# Create a plot — set dimensions, toolbar, and title
plot = figure(tooltips=HOVER_TOOLTIPS,
              tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom',
              x_range=Range1d(-10.1, 10.1), y_range=Range1d(-10.1, 10.1), title=title)

network_graph = from_networkx(G, networkx.spring_layout, scale=10, center=(0, 0))

# Set node size and color
network_graph.node_renderer.glyph = Circle(size=15, fill_color='skyblue')

# Set edge opacity and width
network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5, line_width=1)

# Add network graph to the plot
plot.renderers.append(network_graph)

return plot

运行时报错:

failed to validate StaticLayoutProvider(id='p1075', ...).graph_layout: expected an
element of Dict(Int, Seq(Any)), got {'A': array([-7.94707039, 3.45521447]), 'B':
array([-6.60505319, 4.31869148]), 'C': array([ 8.38746457, -6.26423001]), 'D':
array([ 6.7178286 , -6.63523276]), 'E': array([-5.66671517, 5.25260372]), 'F':
array([10. , -6.53836091]), 'G': array([-4.88645443, 6.41131401])}

错误提示期望Dict(Int, Seq(Any))类型的graph_layout,但实际传入了字符串作为键。使用整数节点ID时可正常绘制,当前使用版本:networkx~=2.8.8、bokeh==3.0.3。

解决方案

这是Bokeh 3.x版本的兼容性问题,在Bokeh 3.0+中,from_networkx生成的布局默认要求节点ID为整数。可通过以下方式解决:

方法1:映射字符串节点为整数ID并保留显示名称

这是最通用的解决方案,适用于任何字符串节点名:

  1. 为字符串节点分配唯一整数ID,重建带节点属性的图:
# 获取所有唯一节点
nodes = list(G.nodes())
node_id_map = {node: idx for idx, node in enumerate(nodes)}

# 构建带整数ID的图,保留边权重属性
G_int = networkx.Graph()
for u, v, attrs in G.edges(data=True):
    G_int.add_edge(node_id_map[u], node_id_map[v], **attrs)

# 给整数节点添加原始名称属性
for node in nodes:
    G_int.nodes[node_id_map[node]]['name'] = node
  1. 调整绘图代码,使用新图并修改hover提示显示原始名称:
HOVER_TOOLTIPS = [("Character", "@name")]
plot = figure(tooltips=HOVER_TOOLTIPS,
              tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom',
              x_range=Range1d(-10.1, 10.1), y_range=Range1d(-10.1, 10.1), title=title)

network_graph = from_networkx(G_int, networkx.spring_layout, scale=10, center=(0, 0))
# 将原始名称传入节点数据源,用于hover显示
network_graph.node_renderer.data_source.data['name'] = [G_int.nodes[n]['name'] for n in G_int.nodes]

方法2:降级Bokeh到2.x版本

如果不需要Bokeh 3.x的新特性,可直接降级到支持字符串节点ID的2.x版本:

pip install bokeh==2.4.3

方法3:转换布局字典键为整数(仅特定场景适用)

仅当节点名称本身是可转换为整数的字符串时使用,比如节点名为"1""2"这类:

# 先生成布局
layout = networkx.spring_layout(G, scale=10, center=(0, 0))
# 转换键为整数
int_layout = {int(k): v for k, v in layout.items()}
# 传入转换后的布局
network_graph = from_networkx(G, lambda G: int_layout, scale=10, center=(0, 0))

内容的提问来源于stack exchange,提问作者unlockme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:15:44