python - 网络中的颜色和权重
问题描述
我想创建一个图表,其中节点根据列中的值具有不同的权重和颜色。
数据样本是
节点 | 重量 | 颜色 | 邻居 |
---|---|---|---|
1 | 23 | 红色的 | [3,5] |
3 | 18 | 蓝色的 | [2] |
4 | 50 | 蓝色的 | [] |
5 | 18 | 蓝色的 | [1] |
2 | 36 | 绿色 | [3] |
上表按节点显示链接:
- 节点 1 与 3 和 5 链接。它的权重为 23,颜色为红色
- 节点 2 与 3 链接。它的权重为 36,颜色为绿色
- 节点 3 与 2 链接。它的权重为 18,颜色为蓝色
- 节点 4 没有链接。它有蓝色和重量 50
- 节点 5 与 1 链接。它的权重为 18,颜色为蓝色
为了建立网络,我做了如下
d = dict(df.drop_duplicates(subset=['Node','Colour'])[['Node','Colour']].to_numpy().tolist())
nodes = G.nodes()
plt.figure(figsize=(30,30))
pos = nx.draw(G, with_labels=True,
nodelist=nodes,
node_color=[d.get(i,'lightgreen') for i in nodes],
node_size=1000)
可惜颜色全错了!另外,我很难添加有关权重的信息。节点之间的关系应该分配给它们的权重。我试过edge_attr='weight'
in nx.draw
, where 'weight' = df['Weight']
。我希望你能给我一些帮助,让我知道我做错了什么。
解决方案
node_color=[d.get(i,'lightgreen') for i in nodes],
这种着色方法不起作用,因为您是根据nodes
而不是根据颜色分配颜色。
“节点之间的关系应该分配给它们的权重。我尝试在 nx.draw 中使用 edge_attr='weight',其中 'weight' = df['Weight']。” *
对于我提出的解决方案,只有节点有权重而不是边。如果您假装这样做,请在数据框中添加一列,例如:
节点 | 重量 | 颜色 | 邻居 | Edge_Weights |
---|---|---|---|---|
1 | 23 | 红色的 | [3,5] | [w1_3,w1_5] |
3 | 18 | 蓝色的 | [2] | [w3_2] |
4 | 50 | 蓝色的 | [] | [] |
5 | 18 | 蓝色的 | [1] | [w5_1] |
2 | 36 | 绿色 | [3] | [w2_3] |
接下来,使用 添加边缘权重G.add_edge(n1,n2,wight=w)
,这里是一些文档。
由于您有多个要添加到节点的属性,因此我建议您使用例如迭代数据框df.itertuples()
。
这是完整的代码:
df = pd.DataFrame( data = {'Node': [1, 3, 4, 5, 2],
'Weight': [23, 18 ,50, 18, 36],
'Colour': ["red", "blue", "blue", "blue", "green"],
'Neighbors': [[3,5], [2], [], [1], [3]]
}
)
NROWS = None
def get_graph_from_pandas(df:
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
for row in df.itertuples(): # row is the row of the dataframe
n = row.Node # change to row.(name of column with the node names)
w = row.Weight # change to row.(name of column with the node weights)
c = row.Colour # change to row.(name of column with the node colors)
neighbors = row.Neighbors
G.add_node(n, weight = w, colour = c)
for neigh in neighbors:
#add edge weights here, attribute of G.add_edge
G.add_edge(n,neigh)
return G
G = get_graph_from_pandas(df)
print("Done.")
print("Total number of nodes: ", G.number_of_nodes())
print("Total number of edges: ", G.number_of_edges())
pos = nx.draw(G, with_labels=True,
node_color=[node[1]['colour'] for node in G.nodes(data=True)],
node_size=200)