Customizing the Pyvis Interactive Network Graphs

Custom Interactive Nwk Graphs FeaImg

In this tutorial, we will be learning how to customize and make the interactive network graphs in Python look much better by adding the available properties to the network graph.

Also read: Create Interactive Network Graphs in Python

There are a number of node properties that can make the visualization pretty interesting, which are listed below:

  1. size – The radius of the node
  2. value – This property scales the radius of the node according to the value passed
  3. title – This property defines the text that appears when the user hovers over the node
  4. x and y values – These properties define the X and Y coordinates of the node
  5. label – The label is the text that appears next to the node.
  6. color – The color of the node is mentioned in this property.

Let’s get started!


Creating a Basic Network Graph with Pyvis

The Pyvis library allows for the creation of interactive network graphs. You can customize these graphs by adding properties to the nodes, such as size, value, title, coordinates, label, color, shape, and border width. This article provides Python code examples for each property.

For this tutorial, we will start off with a simple graph of 10 nodes having random edges which can be built using the python code below.

Begin by importing the right set of libraries. You need these modules imported for all the code snippets:

import random
from pyvis import network as net
from IPython.display import display, HTML

Now, let’s get into the code.

def generate_edge():
  s = random.randint(1,10)
  d = random.randint(1,10)
  return (s,d)

g =  net.Network(height='600px',width='90%',
                  bgcolor='white',font_color="red",
                  heading="A Simple Networkx Graph")

for i in range(1,11):  
  g.add_node(i)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g.add_edge(eg[0],eg[1])
      i+=1

g.show('Simple_Network_Graph.html')
display(HTML('Simple_Network_Graph.html'))

The network graph generated looks somewhat like the one shown below.

Now, we will be working on one node property at a time in the upcoming sections one after another.

Enhancing Your Graph with Node Labels

We can add the label as a label attribute in the add_node function. In this case, the label is set to the node number using the code below. The label argument is the string that will be visible alongside the node in the final visualization.

def generate_edge():
  s = random.randint(1,10)
  d = random.randint(1,10)
  return (s,d)

g_labels =  net.Network(height='600px',width='90%',
                  bgcolor='white',font_color="red",
                  heading="A Simple Networkx Graph with Labels")

for i in range(1,11):  
  g_labels.add_node(i,label=str(i))

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_labels.add_edge(eg[0],eg[1])
      i+=1

g_labels.show('Simple_Network_Graph_labels.html')
display(HTML('Simple_Network_Graph_labels.html'))

The resulting network graph is displayed below.

Scaling Node Sizes for Better Visualization

In this section, we will be adding the size of the node in the form of the value attribute to scale the node to a particular value. To get the random scaling factor, we will be using the function below.

def generate_size_node():
  v = random.randint(5,20)
  return v

Next, we will be adding the value attribute to the add_node function and mention the scaling factor as the value to the value attribute just as we have done in the code below.

def generate_size_node():
  v = random.randint(5,20)
  return v

g_sizes = net.Network(height='600px',width='90%',
                bgcolor='white',font_color="red",
                heading="Network Graph with Different Sizes")

for i in range(1,11):  
  val = generate_size_node()
  g_sizes.add_node(i,label=str(i),value=val)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_sizes.add_edge(eg[0],eg[1])
      i+=1

g_sizes.show('Simple_Network_Graph_sizes.html')
display(HTML('Simple_Network_Graph_sizes.html'))

Here’s what the amazing visualization looks like.

Adding a Splash of Color to Your Nodes

This section will focus on adding various colors to the nodes. We will be generating random colors in the form of hexacode using the function below. We will be adding the color in the form of the color attribute that can also take a plain HTML color like red or blue. We can also specify the full RGBA or hexacode specification as the color below.

Have a look at the code and output below.

def generate_color():
  return '#%06x' % random.randint(0, 0xFFFFFF)

g_colors =net.Network(height='600px',width='90%',
              bgcolor='white',font_color="red",
              heading="Network Graph with Different Colors")

colors=[]
for i in range(1,11):  
  c = generate_color()
  while(c in colors):
      c = generate_color()
  colors.append(c)

  val = generate_size_node()

  g_colors.add_node(i,label=str(i),color=c,value=val)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_colors.add_edge(eg[0],eg[1])
      i+=1

g_colors.show('Simple_Network_Graph_colors.html')
display(HTML('Simple_Network_Graph_colors.html'))

Diversifying Node Shapes for Visual Interest

The shape of the node defines what the node looks like in the final visualization. There are a number of shapes available, including squares, stars, polygons, and others. There are two types of nodes. One type has the label inside of it and the other type has the label underneath it.

Have a look at the code below which will assign shapes to the nodes. Have a look at the final visualization.

def get_random_shape():
  shapes = ['ellipse', 'circle', 'database', 'box', 'text']
  return random.choice(shapes)

g_shapes =net.Network(height='600px',width='90%',
              bgcolor='white',font_color="red",
              heading="Network Graph with Different Shapes")

colors=[]
for i in range(1,11):  
  c = generate_color()
  while(c in colors):
      c = generate_color()
  colors.append(c)

  val = generate_size_node()
  s = get_random_shape()
  
  g_shapes.add_node(i,label=str(i),color=c,value=val,shape=s)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_shapes.add_edge(eg[0],eg[1])
      i+=1

g_shapes.show('Simple_Network_Graph_shapes.html')
display(HTML('Simple_Network_Graph_shapes.html'))

Defining Node Border Width for Clarity

The Border Width of the node defines the width of the border of the node. Have a look at the code below, which will assign border width to the nodes. Have a look at the final visualization.

g_borders =net.Network(height='600px',width='90%',
              bgcolor='white',font_color="red",
              heading="Network Graph with Different BorderWidths")

colors=[]
for i in range(1,11):  
  c = generate_color()
  while(c in colors):
      c = generate_color()
  colors.append(c)

  val = generate_size_node()
  s = get_random_shape()
  b = random.randint(3,5)

  g_borders.add_node(i,label=str(i),color=c,
                    value=val,shape=s,borderWidth=b)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_borders.add_edge(eg[0],eg[1])
      i+=1

g_borders.show('Simple_Network_Graph_Borders.html')
display(HTML('Simple_Network_Graph_Borders.html'))

Bringing It All Together: The Complete Code

Let’s have a look at the code below, which will cover all the custom attributes mentioned above along with a few extra. Along with this, we will also display the physics buttons for the network graphs. We will also add the title for the nodes and we will make the network graph directed to display the arrows of the edges as well.

import random
from pyvis import network as net
from IPython.display import display, HTML

def generate_edge():
  s = random.randint(1,10)
  d = random.randint(1,10)
  return (s,d)

def generate_size_node():
  v = random.randint(5,20)
  return v

def generate_color():
  return '#%06x' % random.randint(0, 0xFFFFFF)

g_complete =net.Network(height='600px',width='50%',
              bgcolor='white',font_color="red",notebook=True,
              heading="A Complete Networkx Graph",directed=True)

colors=[]
for i in range(1,11):  
  c = generate_color()
  while(c in colors):
      c = generate_color()
  colors.append(c)

  val = generate_size_node()
  b = random.randint(3,5)

  g_complete.add_node(i,label=str(i),color=c,value=val,
                      title="Hello! I am Node "+str(i),borderWidth=b)

i=0
chosen_set = []
while(i!=20):
  eg = generate_edge()
  if(eg[0]!=eg[1] and not (eg in chosen_set)):
      chosen_set.append(eg)
      g_complete.add_edge(eg[0],eg[1])
      i+=1

g_complete.show_buttons(['physics'])

g_complete.show('A_Complete_Networkx_Graph.html')
display(HTML('A_Complete_Networkx_Graph.html'))


Conclusion

Through this tutorial, we’ve explored the power of Pyvis in creating interactive and visually appealing network graphs. With just a few lines of code, we’ve added depth and dimension to our nodes. What other properties can you think of that could enhance our network graph further?


References: