IPython & D3

Let's start with a few techniques for working with data in ipython and then build a d3 network graph.


In [ ]:
# import requirments 
from IPython.display import Image
from IPython.display import display
from IPython.display import HTML
from datetime import *
import json
from copy import *
from pprint import *
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import json
from ggplot import *
import networkx as nx
from networkx.readwrite import json_graph
#from __future__ import http_server
from BaseHTTPServer import BaseHTTPRequestHandler
from IPython.display import IFrame
import rpy2
%load_ext rpy2.ipython
%R require("ggplot2")
% matplotlib inline
randn = np.random.randn

JS with IPython?

The nice thing about IPython is that we can write in almost any lanaguage. For example, we can use javascript below and pull in the D3 library.


In [ ]:
%%javascript
require.config({
    paths: {
        //d3: "http://d3js.org/d3.v3.min" //<-- url 
        d3: 'd3/d3.min.js' //<-- local path 
    }
});

Python data | D3 Viz

A basic method is to serialze your results and then render html that pulls in the data. In this example, we save a json file and then load the html doc in an IFrame. We're now using D3 in ipython!

The example below is adapted from:


In [ ]:
import json
import networkx as nx
from networkx.readwrite import json_graph
from IPython.display import IFrame


G = nx.barbell_graph(6,3)
# this d3 example uses the name attribute for the mouse-hover value,
# so add a name to each node
for n in G:
    G.node[n]['name'] = n

# write json formatted data
d = json_graph.node_link_data(G) # node-link format to serialize

# write json
json.dump(d, open('force/force.json','w'))

# render html inline
IFrame('force/force.html', width=700, height=350)
#print('Or copy all files in force/ to webserver and load force/force.html')

Passing data from IPython to JS

Let's create some random numbers and render them in js (see the stackoverflow explanation and discussion).


In [ ]:
from IPython.display import Javascript

import numpy as np
mu, sig = 0.05, 0.2
rnd = np.random.normal(loc=mu, scale=sig, size=4)

## Use the variable rnd above in Javascript:

javascript = 'element.append("{}");'.format(str(rnd))

Javascript(javascript)

Passing data from JS to IPython

We can also interact with js to define python variables (see this example).


In [ ]:
from IPython.display import HTML

input_form = """
<div style="background-color:gainsboro; border:solid black; width:300px; padding:20px;">
Name: <input type="text" id="var_name" value="foo"><br>
Value: <input type="text" id="var_value" value="bar"><br>
<button onclick="set_value()">Set Value</button>
</div>
"""

javascript = """
<script type="text/Javascript">
    function set_value(){
        var var_name = document.getElementById('var_name').value;
        var var_value = document.getElementById('var_value').value;
        var command = var_name + " = '" + var_value + "'";
        console.log("Executing Command: " + command);
        
        var kernel = IPython.notebook.kernel;
        kernel.execute(command);
    }
</script>
"""

HTML(input_form + javascript)

Click "Set Value" then run the cell below.


In [ ]:
print foo

Custom D3 module.

Now we're having fun. The simplicity of this process wins. We can pass data to javascript via a module called visualize that contains an attribute plot_circle, which uses jinja to render our js template. The advantage of using jinja to read our html is apparent: we can pass variables directly from python!


In [ ]:
from pythonD3 import visualize
data = [{'x': 10, 'y': 20, 'r': 15, 'name': 'circle one'}, 
        {'x': 40, 'y': 40, 'r': 5, 'name': 'circle two'},
        {'x': 20, 'y': 30, 'r': 8, 'name': 'circle three'},
        {'x': 25, 'y': 10, 'r': 10, 'name': 'circle four'}]

visualize.plot_circle(data, id=2)

In [ ]:
visualize.plot_chords(id=5)

What's next?

Now we just need to learn how to write useful javacript!
(enter ...the Jason)


In [ ]: