3.5. Adding Color to Nodes#

Graphs where every node is the same color can be difficult to interpret. For this reason, we may want to represent each node as a distinct color given some trait of that node. In the example below, we will use a simple list of Harry Potter characters. We will use their houses to denote node color. Let’s import the same libraries we have worked with so far in this chapter and throughout this textbook.

import networkx as nx
from pyvis.network import Network
import pandas as pd
from IPython.display import HTML

Our data is stored as a csv file which we can load with Pandas.

node_df = pd.read_csv("../data/hp - nodes.csv")
node_df
name house color
0 Harry Gryffindor red
1 Hermione Gryffindor red
2 Ron Gryffindor red
3 Drako Slytherine green
4 Snape Slytherine green
5 Sedric Hufflepuff yellow
6 Luna Ravenclaw blue

Now that we have our data loaded, we can iterate over each Pandas row and populate a list of nodes. Notice, that when we append to nodes, we are not appending a string, rather a tuple. Index 0 of the tuple is the character name, while index 1 is a dictionary. This is where we can store special attributes associated with the node. Think of this as metadata. In our case, we want two pieces of metadata, color and house.

nodes = []
for idx, row in node_df.iterrows():
    nodes.append((row["name"], {"color": row.color, "house": row.house}))
nodes[:1]
[('Harry', {'color': 'red', 'house': 'Gryffindor'})]

Now that we have our node list created, let’s populate it into a NetworkX Graph.

G = nx.Graph()
G.add_nodes_from(nodes)

From here, we can do the same thing with our edge list, which is also stored in a Pandas dataframe. NetworkX has built-in ways of creating a graph from a Pandas edge list, but we will do this manually here.

rel_df = pd.read_csv("../data/hp - rels.csv")
rel_df
source target
0 Harry Hermione
1 Hermione Ron
2 Ron Harry
3 Drako Harry
4 Snape Sedric
5 Sedric Harry
6 Luna Harry
7 Snape Harry
8 Luna Hermione
9 Ron Drako
edge_list = []
for idx, row in rel_df.iterrows():
    edge_list.append((row.source, row.target))
edge_list[:1]
[('Harry', 'Hermione')]

Now that we have our edge list, we can inject it into the same Graph object.

G.add_edges_from(edge_list)

At this stage, our NetworkX Graph is complete with all the data. We can now repeat the steps from the previous section and create our PyVis visualization from the data.

net = Network(notebook=True)
Local cdn resources have problems on chrome/safari when used in jupyter-notebook. 
net.from_nx(G)
net.save_graph("hp_network.html")
HTML(filename="hp_network.html")

We now have a graph with nodes represented with different colors. Notice that the source node controls the edge color by default. NetworkX and PyVis both allow us to control the edge color in the same way as it did with nodes, but instead of adding color as an attribute of the node, we could also assign this to the edge as an attribute.