网络中的颜色和权重

Colour and weights in a network

我想创建一个图表,其中节点根据列中的值具有不同的权重和颜色。

一个数据样本是

Node Weight Colour Neighbours
1 23 red [3,5]
3 18 blue [2]
4 50 blue []
5 18 blue [1]
2 36 green [3]

上面的table按节点显示链接:

为了构建网络,我做了如下操作

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) 

可惜颜色全错了!另外,我很难添加有关权重的信息。 节点之间的关系应该有分配给它们的权重。 我在 nx.draw 中尝试使用 edge_attr='weight',其中 'weight' = df['Weight']。 我希望你能给我一些帮助,让我知道我做错了什么。

node_color=[d.get(i,'lightgreen') for i in nodes], 

这种着色方法不起作用,因为您是根据 nodes 而不是它们的颜色分配颜色。

“节点之间的关系应该分配给它们权重。我在 nx.draw 中尝试使用 edge_attr='weight',其中 'weight' = df['Weight']."*

对于我提出的解决方案,只有节点有权重,边缘没有。如果您假装这样做,请在您的数据框中添加一列,例如:

Node Weight Colour Neighbours Edge_Weights
1 23 red [3,5] [w1_3,w1_5]
3 18 blue [2] [w3_2]
4 50 blue [] []
5 18 blue [1] [w5_1]
2 36 green [3] [w2_3]

接下来,使用 G.add_edge(n1,n2,wight=w) 添加边缘权重,这里是一些 documentation

由于您有多个属性要添加到您的节点,我建议使用例如 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)