In this article I am going to take you through how to create interactive 3D network visualisations in Deepnote using Plotly. This is an image of the beautiful final 3D visualisation of Zachary's Karate Club that we are working towards:
This article is going to be all about network visualisations,or more specifically how to create ineractive 3D networks in deepnote. We are going to do this using the python packages networkx and Plotly. If you are interestd in the fundamentals of networks and their potential applications do have a look at my last [article](link) on social network analysis.
We are going to walk through how to produce a 3D visualisation of the Zachary Karate Club graph that we worked within my last article.
In my last post we used networkx to make our visualisations. That just about did the job, but now are going to explore using Plotly to make some more sophisticated visualisations. The open source software [Gephi](https://gephi.org/)is also often used for visualisations, but Plotly is usually easier to use as it means we can do everything in python and never have to leave our Deepnote notebook!
The first step is to get all of the python packages we need installed and imported. We will also open the Zachary's Karate Club (ZKC) graph,andset-up some variables to hold other useful information.
#Import the required packagesimport networkx as nx
import plotly.graph_objects as go
import pandas as pd
#Let's import the ZKC graph:
ZKC_graph = nx.karate_club_graph()#Let's keep track of which nodes represent John A and Mr Hi
John_A =33#remember the number of nodes since this will come in useful later
Num_nodes =34#get the club labels - i.e. which club each individual ended up joining
In the visualisation we want to distinguish between the different communities detected in my last [article](link). We want to visualise these two communities (our predictions for which faction each individual will join)in a different colour. For ease they are included here:
#communities from last time - one list for each community
community_1 =[0,1,2,3,4,5,6,7,9,10,11,12,13,16,17,19,21]#label for each node corresponds to community 0 or community 1
## Visualisation using NetworkX
As a reminder of what we are able to do using networkx lets create a quick 2D visualisation.
A convenient feature of using networkx for plots is that we can very easily choose the positions of our nodes using different networkx functions. Last time we used a circular layout, this time we will use a [spring layout](https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html).
#Let's opt for a spring layout
spring_pos = nx.spring_layout(ZKC_graph, seed=2)
#draw the network
nx.draw_networkx_nodes(ZKC_graph, spring_pos, nodelist=community_0, node_color='g', alpha=0.4)
nx.draw_networkx_nodes(ZKC_graph, spring_pos, nodelist=community_1, node_color='m', alpha=0.4)#let's highlight Mr Hi (solid purple) and John A (solid green)
nx.draw_networkx_nodes(ZKC_graph, spring_pos, nodelist=[John_A], node_color='g', alpha=1)
nx.draw_networkx_nodes(ZKC_graph, spring_pos, nodelist=[Mr_Hi], node_color='m', alpha=1)
nx.draw_networkx_edges(ZKC_graph, spring_pos,stlye='dashed',width =0.5)
The benefit of this spring layout is that it makes the distinctions between the two detected communities very clear. We can see that both of the communities are clustered around their 'leader'(Mr Hi or John A.).
This matplotlib plot however is ultimately limited, it is tightly packed and it's hard to tell exactly what is going on. To improve on this let's see what can be done with Plotly.
## On to Plotly!
It's really easy to use Plotly in deepnote to create a 3D visualisation of a network. Essentially, we are going to make seperate 3D scatter plots (or traces in common Plotly terminology) of the nodes and the edges which will then be plotted together.
#As before we use networkx to determine node positions. We want to do the same spring layout but in 3D
spring_3D = nx.spring_layout(ZKC_graph,dim=3, seed=18)#an example node coordinate
#we need to seperate the X,Y,Z coordinates for Plotly
x_nodes =[spring_3D[i]for i inrange(Num_nodes)]# x-coordinates of nodes
y_nodes =[spring_3D[i]for i inrange(Num_nodes)]# y-coordinates
z_nodes =[spring_3D[i]for i inrange(Num_nodes)]# z-coordinates
#We also need a list of edges to include in the plot
edge_list = ZKC_graph.edges()
#we need to create lists that contain the starting and ending coordinates of each edge.
z_edges=#need to fill these with all of the coordiatesfor edge in edge_list:#format: [beginning,ending,None]
x_edges += x_coords
y_edges += y_coords
z_edges += z_coords
#create a trace for the edges
trace_edges = go.Scatter3d(x=x_edges,
Before diving into creating a trace for the nodes I want to highlight one of Plotly's most useful features: Hover Labels. It lets the user to reveal more information about a data point by moving their mouse cursor over the point and having a hover label appear. Here we set the hoverinfo to 'text' and the text to the club labels that we retreived at the beginning.
That means in the visualisation we will be able to find out which faction an individual ended up joining just by hovering our mouse close to the node.
#create a trace for the nodes
trace_nodes = go.Scatter3d(x=x_nodes,
color=community_label,#color the nodes according to their community
colorscale=['lightgreen','magenta'],#either green or mageneta
To clearly highlight Mr Hi and John A. We need to plot their nodes again in another colour. The simplest way to do this is to create another trace for each node. These will then be plotted on top of the other nodes.
#we need to set the axis for the plot
#also need to create the layout for our plot
layout = go.Layout(title="Two Predicted Factions of Zachary's Karate Club",
### Now we have got everything sorted here is our plot!
#Include the traces we want to plot and create a figure
data =[trace_edges, trace_nodes, trace_MrHi, trace_JohnA]
fig = go.Figure(data=data, layout=layout)
Great! So there we have it. A 3D visualisation of our Zachary Karate Club graph. The two communities (purple and green) represent our predictions for which faction each individual will join. Whilst the dark purple and dark green nodes represent Mr Hi and John A respectively.
If you hover your mouse over the different nodes it will also tell you which faction the individual actually chose to join. In my last article our predictions were wrong for two individuals. See if you can find them (hint they are near the centre of the graph).
## What about a more complicated example?
The internet is a typical example when it comes to complex networks. In fact, it is this insight, modelling the internet as a network, that allows Google to return effective [search results](https://en.wikipedia.org/wiki/PageRank).
Below is a 3D visualisation of a network 2000 different webpages, generated from[networkx](https://networkx.github.io/documentation/stable/reference/generated/networkx.generators.internet_as_graphs.random_internet_as_graph.html)(feel free to play around with it, it's also interactive!). The colors represent different communities that were detected.
That's it for this article, but I hope it has given you everything you need to know to open up your own Deepnote notebook and have a play around with your own visualisations!