Codementor Events

VIS.JS Visualization in Jupyter Notebook

Published Apr 14, 2017
VIS.JS Visualization in Jupyter Notebook

Visualization in Jupyter Notebook using vis.js

What is vis.js?

vis.js is a dynamic, browser-based visualization library. The library is designed to be easy to use, to handle large amounts of dynamic data, and to enable manipulation of and interaction with the data. It allows us to visualize data in a variety of forms and to add control on physics options.
Download page: vis.js

What is Jupyter?

The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and explanatory text.
Download page: jupyter

What is Anaconda?

Anaconda is the leading open data science platform powered by Python. It bundles Jupyter Notebook and includes over 100 of the most popular Python, R and Scala packages for data science.
Download page: anaconda

Why should I care?

The reason for Jupyter Notebook success is it excels in the form of programming called literate programming. Literate programming is a software development style pioneered by Stanford computer scientist, Donald Knuth. This type of programming emphasizes a prose first approach where exposition with human-friendly text is punctuated with code blocks. It excels at demonstration, research, and teaching objectives especially for science.
By adding advanced visualization tools in combining with javascript, we can extend its functionality to add fine grain tuning.

Quick Notes

  1. We will use Anaconda 4.3.1 with Python 3.6 version.
  2. vis.js version 4 is used to visualize the graph.
  3. Javascript and Python knowledge is advised for this tutorial.
  4. This tutorial doesn't dwell into configuring and installing anaconda.

Installing Required Library

Before we start, we will need anaconda, which bundles Jupyter Notebook and a bunch of useful libraries.
Once installed we will download vis.ja and unzip it into the desired location.
fs01.png
We will need to configure vis.js ditribution folder inside .jupyter/jupyter_notebook_config.py by adding the following line (where dist is the location of the distribution folder of vis.js libraries.):

c.NotebookApp.extra_static_paths = ["/Users/isai/Documents/Jupyter/Viz/dist"]

c01.png
c02.png

Starting Jupyter Notebook

To start Jupyter Notebook open a terminal and execute:

jupyter notebook

startJN.png
Once the notebook starts, our default browser will open the Jupyter navigator. We will create a new file in the desired location.

Creating the Visualization

There are two options to showcase networks with vis.js,

  1. Processing the information in Javascript and displaying the results using inline HTML.
  2. Processing the information in Python, sending it to an inline Javascript and showing it in inline HTML.

Optionally we can have physics controls in an inline HTML

Inline Javascript

To display javascript in Jupyter Notebook, we will first create a python cell in which we will import the needed iPython library required to show HTML snippets.

from IPython.core.display import display, HTML
from string import Template
import json

The next step is to create an inline HTML object that will contain the visualization. Here, we create a div element in the notebook.

%%html
<div id="mynetwork"></div>

And finally we add an inline javascript cell which uses require to specify the vis.js library that we previously added to the jupyter configuration, we create a network and add the container div element to it.

%%javascript
requirejs.config({
    paths: {
        vis: 'vis'
    }
});

require(['vis'], function(vis){
    
    var nodes = [
        {id: 1, label: 'Beyonce', group: 'United States'},
        {id: 2, label: 'Barak Obama', group: 'United States'},
        {id: 3, label: 'Miley Cyrus', group: 'United States'},
        {id: 4, label: 'Pope Francis', group: 'Vatican'},
        {id: 5, label: 'Vladimir Putin', group: 'Rusia'}
    ];

    // create an array with edges
    var edges = [
        {from: 1, to: 2},
        {from: 1, to: 3},
        {from: 2, to: 4},
        {from: 2, to: 5}
    ];

    // create a network
    var container = document.getElementById('mynetwork');
    var data= {
        nodes: nodes,
        edges: edges,
    };
    var options = {
        width: '800px',
        height: '400px'
    };
    
    var network = new vis.Network(container, data, options);
});

Once we run all the cells, we get the following visualization under the HTML cell.

inline_ex01.png

Python to Inline Javascript

Now, we're going to display this graph in the notebook with vis.js receiving the data from Python. The first step is to bring this graph to Javascript. We choose here to export the graph in JSON. Since we want to avoid saving the JSON file to disk, we translate the data to the frontend.
Note that vis.js expects each edge to be an object with a source and a target.

from IPython.core.display import display, HTML
from string import Template

nodes = [
        {'id': 1, 'label': 'Beyonce', 'group': 'United States'},
        {'id': 2, 'label': 'Barak Obama', 'group': 'United States'},
        {'id': 3, 'label': 'Miley Cyrus', 'group': 'United States'},
        {'id': 4, 'label': 'Pope Francis', 'group': 'Vatican'},
        {'id': 5, 'label': 'Vladimir Putin', 'group': 'Rusia'}
]

edges = [
        {'from': 1, 'to': 2},
        {'from': 1, 'to': 3},
        {'from': 2, 'to': 4},
        {'from': 2, 'to': 5}
]

This one’s a bit of a hack. Since the %javascript magic is run client-side, the window is set. So we bind data to the window so that it’s globally accessible.
All browsers support the window object. It represents the browser's window. All global JavaScript objects, functions, and variables automatically become members of the window object. Global variables are properties of the window object.
But wait, it gets better: Python JSON.dumps transform the output into a JSON string! The only trick now is managing to execute some JS code that loads the JSON dump.

from IPython.display import Javascript
import json

# Transform the graph into a JSON graph
data = {"nodes":nodes, "edges":edges}
jsonGraph = json.dumps(data, indent=4)

# Send to Javascript
Javascript("""window.jsonGraph={};""".format(jsonGraph))

The next step is to create an inline HTML object that will contain the visualization. Here, we create a div element in the notebook.

%%html
<div id="mynetwork"></div>

And finally, we add an inline Javascript cell which receives the nodes and edges from the global window.jsonGraph variable.

%%javascript
requirejs.config({
    paths: {
        vis: 'vis'
    }
});

require(['vis'], function(vis){
    
    // create a network
    var container = document.getElementById('mynetwork');
    var options = {
        width: '800px',
        height: '400px'
    };
    
    // We load the JSON graph we generated from iPython input
    var graph = window.jsonGraph;
    
    // Display Graph
    var network = new vis.Network(container, graph, options);
});

Once we run all the cells, we get the following visualization under the HTML cell.

inline_ex02.png

Wrapping Things Up

By adding vis.jsvisualization to Jupyter, we are extending the functionality and allowing us to process and retrieve the data in Python while showing its visualization in Javascript which not only displays the graph but also makes it possible to add physics controls and personalized actions.

Have You Try The Following

Now that you know the basics, how about checking some examples from vis.js and implementing them.
How about adding physics controls?

Play around and check what happens. Create your own visualization; the idea is to learn new things. If you like this tutorial, share it with your friends. 😉

Discover and read more posts from Isai B. Cicourel
get started
post comments3Replies
Ray Ronnaret
4 years ago

I follow the article but not work.
I put below and the notebook output nothing.

c.NotebookApp.extra_static_paths = ["/Users/ray/anaconda3/dist"]

Also i try Jupyter Lab and it return

“Javascript Error: requirejs is not defined”

Any suggestion?

Dana Moore
6 years ago

Wonderful technical post! I went straight from your very clear tutorial to an implementation

Thank you much
Josh
6 years ago

Thanks for the tutorial!
I’m trying to do the same but with vis timeline. And somehow the js object is undefined. I assume that issue is here:

Javascript(""“window.jsonTimeline={};”"".format(jsonTimeline))

In the same cell I have a debug output which shows that jsonTimeline is correct formatted but in the js cell then window.jsonTimeline somehow is then undefined.

Any idea?