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

使用toyplot绘制社区图时节点颜色映射异常问题排查

问题:Toyplot社区图颜色映射异常问题

我用Toyplot绘制带有源节点、目标节点的社区图,节点分属社区0和社区1,希望社区0节点显示为绿色、社区1节点显示为橙色,但颜色映射始终不正确。当把节点重命名为0-9(使用source2和target2字段)时,生成的图颜色显示正常,请问我忽略了什么问题?

import numpy as np
import pandas as pd
import toyplot

nodes = ['1001', '1002', '1006', '100e', '010c', '0521', '0513', '0710', '0711', '1005']

mapped_nodes = ['0','1','2','3','4','5','6','7','8','9']
event_map = dict(zip(nodes,mapped_nodes))

edges = pd.DataFrame()
edges['source'] = ['010c','0513','0513','0513','0513','0513','0521','0521','0521','0521','0710','0710','0710','1001','1002','1006']
edges['target'] = ['0521','0521','0710','0711','1001','1005','0710','1001','1002','1006','1006','0711','1005','1006','1006','100e']
edges['source2'] = edges['source'].map(event_map)
edges['target2'] = edges['target'].map(event_map)
print('display edges')
display(edges)

# 启用这行时节点颜色显示正常
# edges = np.array(edges[['source2','target2']].values.tolist())

# 启用这行时节点颜色显示异常,1005、0711、0513、0710本应显示社区1的颜色
edges = np.array(edges[['source','target']].values.tolist())

print('print edges')
print(edges)

assigned = pd.DataFrame()
assigned['target'] = ['1001','1002','1006','100e','010c','0521','0513','0710','0711','1005']
assigned['target2'] = assigned['target'].map(event_map)
assigned['community'] = [0,0,0,0,0,0,1,1,1,1]
print('display assigned')
display(assigned)
assigned = np.array(assigned[['target','target2','community']].values.tolist())
print('print assigned')
print(assigned)

colormap = toyplot.color.brewer.map("Set2")
display(colormap)

ecolor = "lightgrey"
vlstyle = {"fill":"white"}
vcolor = assigned[:,2].astype(int)
toyplot.graph(edges, ecolor=ecolor, vsize=20, vlstyle=vlstyle, vcolor=(vcolor, colormap))

问题根源

Toyplot的toyplot.graph()函数处理字符串类型的节点ID时,会自动按字符串的字典序为节点分配索引;而你传入的vcolor是按照自定义的assigned数组顺序排列的,两者的节点顺序不匹配,导致颜色对应错位。

当使用数字字符串(0-9)作为节点ID时,Toyplot的字典序排序刚好和你assigned里的target2顺序一致,所以颜色匹配正确;但使用原始字符串节点ID时,排序顺序和你定义的节点社区顺序完全不同,自然出现颜色映射错误。

解决方法

只需让vcolor的顺序和Toyplot内部生成的节点顺序完全一致,以下是两种可行方案:

方案1:手动指定节点顺序

调用toyplot.graph()时,通过nodes参数明确指定节点顺序,和assigned里的target顺序保持一致:

# 提取自定义的节点顺序
node_order = assigned[:,0].tolist()
# 绘制时传入nodes参数锁定顺序
toyplot.graph(edges, nodes=node_order, ecolor=ecolor, vsize=20, vlstyle=vlstyle, vcolor=(vcolor, colormap))

方案2:按Toyplot节点顺序重排颜色数组

先生成图对象获取内部节点顺序,再重新排列颜色数组:

# 先创建图对象,获取Toyplot自动排序后的节点列表
graph = toyplot.graph(edges, ecolor=ecolor, vsize=20, vlstyle=vlstyle)
toyplot_nodes = graph.nodes.keys()

# 创建节点-社区映射字典
community_map = dict(zip(assigned[:,0], assigned[:,2].astype(int)))
# 按Toyplot节点顺序生成对应颜色
sorted_vcolor = [community_map[node] for node in toyplot_nodes]

# 更新节点颜色
graph.nodes.color = (sorted_vcolor, colormap)

效果验证

两种方案都能让原始字符串节点ID的颜色匹配正确,社区0显示绿色、社区1显示橙色,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 12:25:02