iPython and Jupyter Notebook with Embedded D3.js
There have been several tries to incorporate D3 into IPython:
Though quite progresses have been made in those approaches, they were kind of hacks. Now, we have language agnostic Jupyter which was forked from IPython, we can take the D3 into Notebook without lots of effeorts.
We can start implement D3 into Jupyter from this repo: PyGoogle/PyD3.
The repo is based on this presentation:
The primary idea looks like this:
- Jupyter reads in HTML DOM as a string via IPython.core.display
- DOM elements manipulation using Python's string.Template.substitute
- Data format - Panda's JSON
from IPython.core.display import HTML HTML(''' <h1>Hello DOM!</h1> ''')So, Jupyter simply imports D3 using HTML API
HTML('<script src="lib/d3/d3.min.js"></script>')
Before we use Jupyter, we'll use the following D3 animation.
Here is the pure D3 animation.
Here is the code for D3 animaition:
<div class="legend">SVG circle with animation - to see it again, refresh the browser:</div> <div id="bogo_animation"></div> <script type="text/javascript"> var bogoSVG = d3.select("#bogo_animation") .append("svg") .attr("width", 300) .attr("height", 300); bogoSVG.append("circle") .style("stroke", "gray") .style("fill", "cyan") .attr("r", 130) .attr("cx", 150) .attr("cy", 150) .transition() .delay(100) .duration(10000) .attr("r", 10) .attr("cx", 150) .style("fill", "blue"); </script>
We're using the same animation showed in the previous section.
The code for Notebook looks like this:
from IPython.core.display import display, HTML from string import Template import json HTML('') css_text = ''' ''' js_text_template = Template(''' var bogoSVG = d3.select("#$bogoanimation") .append("svg") .attr("width", 300) .attr("height", 300); var data = $python_data ; bogoSVG.append("circle") .style("stroke", "gray") .style("fill", "cyan") .attr("r", data[0]['r']) .attr("cx", data[0]['cx']) .attr("cy", data[0]['cy']) .transition() .delay(100) .duration(10000) .attr("r", 10) .attr("cx", data[0]['cx']) .style("fill", "blue"); ''') html_template = Template(''' ''') js_text = js_text_template.substitute({'python_data': json.dumps([{'r': 130, 'cx': 150, 'cy': 150}]), 'bogoanimation': 'animation'}) HTML(html_template.substitute({'css_text': css_text, 'js_text': js_text}))
Notebook is available at Github:
PyD3/D3-Circle-Animation.ipynb
Note: This is an email I got from a reader:
hi K Hong,
I was just reading your post regarding embedding d3 in jupyter notebooks:
http://www.bogotobogo.com/python/IPython/iPython_Jupyter_Notebook_with_Embedded_D3.php
It seems there is an issue importing d3 as an external library:
see https://github.com/mpld3/mpld3/issues/33#issuecomment-32101013
(I had the same issue)
the solution was to place the usage of d3 within a require:
require.config({paths: {d3: "http://d3js.org/d3.v3.min"}}); require(["d3"], function(d3) { // code that uses D3 goes hereā¦ // e.g., console.log(d3.version); });
this worked for me.
you can se an example for how to get your code to work with this fix here:
https://github.com/fensterheim/DataProjects/blob/master/D3_example/D3Test.ipynb
according to the issue that was opened it seems that this is a problem with newer versions of d3, therefore it might be worth while noting this in your blog post.
IPython: Jupyter
- iPython and Jupyter - Install Jupyter, iPython Notebook, drawing with Matplotlib, and publishing it to Github
- iPython and Jupyter Notebook with Embedded D3.js
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization