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.