Pleastry
Pleastry

Reputation: 434

Changing the color of specific nodes using graphviz after generating source

I have a python dataframe that I would like to visualize in graphviz. Everything works fine except that I would like to change the color of the nodes after plotting the network.

The dataframe looks something like this:

Sender   Receiver   Amount     Sender_Part_Of_Group?          Receiver_Part_Of_Group?
A        B          88         1                              0
C        B          71         0                              0
B        D          32         0                              1
D        A          26         1                              1

I used G = nx.convert_matrix.from_pandas_edgelist(df,"Sender","Receiver","Amount", create_using = nx.multiDiGraph()) to create a NetworkX object.

I then used dot = nx.nx_pydot.to_pydot(G) to create a dot object.

Finally, I did this:

from graphviz import Source
sc = Source(dot, filename = "plot", format = "png", engine = "fdp")
sc.render

This is the graph that I got.

enter image description here

Now I want to color all of the nodes based on whether they are part of the group (last two columns of the df) or not. What is the best way to go forward with this? I don't want to construct the nodes and edges manually because the DataFrame is quite large. This is what I would ideally prefer to have since A and D are part of the group and B and C are not:

enter image description here

Upvotes: 3

Views: 2453

Answers (1)

CDJB
CDJB

Reputation: 14516

You can do this by looping over each row of the DataFrame and setting the attributes of each node. The attributes we are interested in are 'style' and 'color'. We want to check if either the Sender or the Receiver is in the group, and if so, color either the sender or receiver node accordingly.

from graphviz import Source
import pandas as pd
import networkx as nx

df = pd.DataFrame({'Sender': {0: 'A', 1: 'C', 2: 'B', 3: 'D'},
 'Receiver': {0: 'B', 1: 'B', 2: 'D', 3: 'A'},
 'Amount': {0: 88, 1: 71, 2: 32, 3: 26},
 'Sender_Part_Of_Group?': {0: 1, 1: 0, 2: 0, 3: 1},
 'Receiver_Part_Of_Group?': {0: 0, 1: 0, 2: 1, 3: 1}})

G = nx.convert_matrix.from_pandas_edgelist(df,"Sender","Receiver","Amount", create_using = nx.MultiDiGraph())

for i, row in df.iterrows():
    G.nodes[row['Sender']]['style'] = 'filled'
    if row['Sender_Part_Of_Group?']:
        G.nodes[row['Sender']]['color'] = 'red'
    else:
        G.nodes[row['Sender']]['color'] = 'blue'
    if row['Receiver_Part_Of_Group?']:
        G.nodes[row['Receiver']]['color'] = 'red'
    else:
        G.nodes[row['Receiver']]['color'] = 'blue'

dot = nx.nx_pydot.to_pydot(G)

sc = Source(dot, filename = "plot", format = "png", engine = "fdp")
sc.render()

Giving us:

enter image description here

Upvotes: 1

Related Questions