Reputation: 567
I would like to create a graph where nodes have a different weight and colour based on values in columns.
A sample of data is
Node | Weight | Colour | Neighbours |
---|---|---|---|
1 | 23 | red | [3,5] |
3 | 18 | blue | [2] |
4 | 50 | blue | [] |
5 | 18 | blue | [1] |
2 | 36 | green | [3] |
The table above shows the links by nodes:
For building the network I have done as follows
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)
Unfortunately the colours are all wrong! Also, I have difficulties to add information on weights.
The ties among nodes should have weights assigned to them.
I have tried with edge_attr='weight'
in nx.draw
, where 'weight' = df['Weight']
.
I hope you can give me some help and let me know what I have done wrong.
Upvotes: 1
Views: 259
Reputation: 1852
node_color=[d.get(i,'lightgreen') for i in nodes],
This method of coloring didn't work because you are assigning colors according to the nodes
instead of their colours.
"The ties among nodes should have weights assigned to them. I have tried with edge_attr='weight' in nx.draw, where 'weight' = df['Weight']."*
For the solution I present, only the nodes have weights not the edges. If you pretend to do this, add a column on your data frame, e.g:
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] |
Next, add edge weight using G.add_edge(n1,n2,wight=w)
, here is some documentation.
Since you have multiple attributes you want to add to your nodes I would recommend iterating through your dataframe using for example df.itertuples()
.
Here is the full code:
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)
Upvotes: 1