Skip to content

Instantly share code, notes, and snippets.

@bartaelterman
Created April 15, 2016 14:30
Show Gist options
  • Save bartaelterman/7b821a9cd9cf211e6e81ab91e438bfba to your computer and use it in GitHub Desktop.
Save bartaelterman/7b821a9cd9cf211e6e81ab91e438bfba to your computer and use it in GitHub Desktop.
js viz in jupyter
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data visualizations with D3js in a Jupyter notebook"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we will demonstrate how you can use D3 to visualize data in a notebook. Admitted, D3 is not the most handy tool for researchers since it's a very verbose way to construct a visalization (as you will see later on). However, D3 allows you to create any chart you want and customize it exactly how you want it. Furthermore custom interactions with the visualization can be defined that can allow users to truly interact with the data.\n",
"\n",
"I won't say every researcher should learn D3js - or any other JavaScript plotting library for that matter - but if you have JS proficient people, they can help to make notebooks even more interactive for researchers.\n",
"\n",
"Let's kick off with importing some required packages."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import pandas\n",
"import pprint\n",
"import json\n",
"from IPython.display import Javascript, HTML"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's construct a simple dataframe."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>age</th>\n",
" <th>height</th>\n",
" <th>name</th>\n",
" <th>sex</th>\n",
" <th>weight</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>28</td>\n",
" <td>185</td>\n",
" <td>Jan</td>\n",
" <td>male</td>\n",
" <td>84</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>34</td>\n",
" <td>177</td>\n",
" <td>Piet</td>\n",
" <td>male</td>\n",
" <td>82</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>22</td>\n",
" <td>180</td>\n",
" <td>Joris</td>\n",
" <td>male</td>\n",
" <td>78</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>42</td>\n",
" <td>172</td>\n",
" <td>Korneel</td>\n",
" <td>male</td>\n",
" <td>81</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>12</td>\n",
" <td>157</td>\n",
" <td>Lisa</td>\n",
" <td>female</td>\n",
" <td>48</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" age height name sex weight\n",
"0 28 185 Jan male 84\n",
"1 34 177 Piet male 82\n",
"2 22 180 Joris male 78\n",
"3 42 172 Korneel male 81\n",
"4 12 157 Lisa female 48"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = pandas.DataFrame(data={\n",
" 'age': [28, 34, 22, 42, 12],\n",
" 'height': [185, 177, 180, 172, 157],\n",
" 'weight': [84, 82, 78, 81, 48],\n",
" 'name': ['Jan', 'Piet', 'Joris', 'Korneel', 'Lisa'],\n",
" 'sex': ['male', 'male', 'male', 'male', 'female']\n",
" })\n",
"a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First of all, Jupyter notebooks allow you to use html and javascript as demonstrated by the next two cells:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div id=\"testdiv\"><h1>See?</h1></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<div id=\"testdiv\"><h1>See?</h1></div>"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"alert('and see?');"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"alert('and see?');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This allows us to import external JavaScript libraries, and use them to manipulate the DOM of the notebook. Let's download D3.js"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<script src=\"https://d3js.org/d3.v3.min.js\" charset=\"utf-8\"></script>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<script src=\"https://d3js.org/d3.v3.min.js\" charset=\"utf-8\"></script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There, we can now use D3 to add a paragraph to the `h1` element we created above."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"d3.select(\"#testdiv\").append(\"p\").text(\"This paragraph was added using D3.\");"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"d3.select(\"#testdiv\").append(\"p\").text(\"This paragraph was added using D3.\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The amount of visualization possibilities is now virtually endless. Let's use D3 to create a scatter plot based on the dataframe we defined at the top of this notebook. Because we are now building the notebook ourselves, we can add custom interactions to the viz.\n",
"\n",
"Note that in JavaScript, data is used as JSON. So we'll convert the dataframe into a JavaScript-friendly format."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[{'age': 28, 'height': 185, 'name': 'Jan', 'sex': 'male', 'weight': 84},\n",
" {'age': 34, 'height': 177, 'name': 'Piet', 'sex': 'male', 'weight': 82},\n",
" {'age': 22, 'height': 180, 'name': 'Joris', 'sex': 'male', 'weight': 78},\n",
" {'age': 42, 'height': 172, 'name': 'Korneel', 'sex': 'male', 'weight': 81},\n",
" {'age': 12, 'height': 157, 'name': 'Lisa', 'sex': 'female', 'weight': 48}]\n"
]
}
],
"source": [
"data = list(a.T.to_dict().values())\n",
"pprint.pprint(data)\n",
"\n",
"json_data = json.dumps(list(a.T.to_dict().values()))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here is the most ugly part of the concept. To make our JSON data available to cells processing JavaScript, we'll append it to the global `window` object."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" window.vizObj=[{\"name\": \"Jan\", \"height\": 185, \"weight\": 84, \"age\": 28, \"sex\": \"male\"}, {\"name\": \"Piet\", \"height\": 177, \"weight\": 82, \"age\": 34, \"sex\": \"male\"}, {\"name\": \"Joris\", \"height\": 180, \"weight\": 78, \"age\": 22, \"sex\": \"male\"}, {\"name\": \"Korneel\", \"height\": 172, \"weight\": 81, \"age\": 42, \"sex\": \"male\"}, {\"name\": \"Lisa\", \"height\": 157, \"weight\": 48, \"age\": 12, \"sex\": \"female\"}];\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Javascript(\"\"\"\n",
" window.vizObj={};\n",
" \"\"\".format(json_data))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now access our json data using JavaScript:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"alert(JSON.stringify(window.vizObj));"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"alert(JSON.stringify(window.vizObj));"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Before we define our plotting function, let's first set some styles for our visualization. Using the `%%html` function, we can define CSS styles in a `<style>` tag."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<style>\n",
"\n",
"svg {\n",
" font: 10px sans-serif;\n",
"}\n",
"\n",
".axis path,\n",
".axis line {\n",
" fill: none;\n",
" stroke: #000;\n",
" shape-rendering: crispEdges;\n",
"}\n",
"\n",
".tooltip {\n",
" position: absolute;\n",
" width: 200px;\n",
" height: 28px;\n",
" pointer-events: none;\n",
" font: 10px sans-serif;\n",
"}\n",
"\n",
"</style>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<style>\n",
"\n",
"svg {\n",
" font: 10px sans-serif;\n",
"}\n",
"\n",
".axis path,\n",
".axis line {\n",
" fill: none;\n",
" stroke: #000;\n",
" shape-rendering: crispEdges;\n",
"}\n",
"\n",
".tooltip {\n",
" position: absolute;\n",
" width: 200px;\n",
" height: 28px;\n",
" pointer-events: none;\n",
" font: 10px sans-serif;\n",
"}\n",
"\n",
"</style>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now on to D3 for the visualization. D3 is rather verbose when it comes to plotting, but other JavaScript libraries (often built on top of D3) could be used as well."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"var plotit = function() {\n",
" var margin = {top: 20, right: 20, bottom: 30, left: 40},\n",
" width = 960 - margin.left - margin.right,\n",
" height = 500 - margin.top - margin.bottom;\n",
"\n",
" var x = d3.scale.linear()\n",
" .range([0, width]);\n",
"\n",
" var y = d3.scale.linear()\n",
" .range([height, 0]);\n",
"\n",
" var color = d3.scale.category10();\n",
"\n",
" var xAxis = d3.svg.axis()\n",
" .scale(x)\n",
" .orient(\"bottom\");\n",
"\n",
" var yAxis = d3.svg.axis()\n",
" .scale(y)\n",
" .orient(\"left\");\n",
"\n",
" var svg = d3.select(\"#scatterplot\").append(\"svg\")\n",
" .attr(\"width\", width + margin.left + margin.right)\n",
" .attr(\"height\", height + margin.top + margin.bottom)\n",
" .append(\"g\")\n",
" .attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\n",
"\n",
" var tooltip = d3.select(\"body\").append(\"div\")\n",
" .attr(\"class\", \"tooltip\")\n",
" .style(\"opacity\", 0);\n",
"\n",
" x.domain([0, d3.extent(window.vizObj, function(d) {return d.age})[1]]);\n",
" y.domain([0, d3.extent(window.vizObj, function(d) {return d.height})[1]]);\n",
"\n",
" svg.append(\"g\")\n",
" .attr(\"class\", \"x axis\")\n",
" .attr(\"transform\", \"translate(0,\" + height + \")\")\n",
" .call(xAxis)\n",
" .append(\"text\")\n",
" .attr(\"class\", \"label\")\n",
" .attr(\"x\", width)\n",
" .attr(\"y\", -6)\n",
" .style(\"text-anchor\", \"end\")\n",
" .text(\"Age\");\n",
"\n",
" svg.append(\"g\")\n",
" .attr(\"class\", \"y axis\")\n",
" .call(yAxis)\n",
" .append(\"text\")\n",
" .attr(\"class\", \"label\")\n",
" .attr(\"transform\", \"rotate(-90)\")\n",
" .attr(\"y\", 6)\n",
" .attr(\"dy\", \".71em\")\n",
" .style(\"text-anchor\", \"end\")\n",
" .text(\"Height (cm)\");\n",
"\n",
" svg.selectAll(\"circle\")\n",
" .data(window.vizObj)\n",
" .enter().append(\"circle\")\n",
" .attr(\"r\", function(d) {return (d.weight - 30)/ 5})\n",
" .attr(\"cx\", function(d) { return x(d.age); })\n",
" .attr(\"cy\", function(d) { return y(d.height); })\n",
" .attr(\"fill\", function(d) {if (d.sex == \"male\") {return \"#3182bd\"} else {return \"#ef3b2c\"}})\n",
" .attr(\"opacity\", .6)\n",
" .attr(\"stroke\", \"black\")\n",
" .attr(\"stroke-width\", 0)\n",
" .on(\"mouseover\", function(d) {\n",
" d3.select(this).attr(\"opacity\", 1).attr(\"stroke-width\", 1);\n",
" tooltip.transition()\n",
" .duration(100)\n",
" .style(\"opacity\", .9);\n",
" tooltip.html(d.name + \"<br/> (\" + d.age + \": \" + d.height + \"cm)\")\n",
" .style(\"left\", (d3.event.pageX + 15) + \"px\")\n",
" .style(\"top\", (d3.event.pageY + 10) + \"px\");\n",
" })\n",
" .on(\"mouseout\", function(d) {\n",
" d3.select(this).attr(\"opacity\", .6).attr(\"stroke-width\", 0);\n",
" tooltip.transition()\n",
" .duration(500)\n",
" .style(\"opacity\", 0);\n",
" });\n",
"};\n",
"window.plotit = plotit;"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"var plotit = function() {\n",
" var margin = {top: 20, right: 20, bottom: 30, left: 40},\n",
" width = 960 - margin.left - margin.right,\n",
" height = 500 - margin.top - margin.bottom;\n",
"\n",
" var x = d3.scale.linear()\n",
" .range([0, width]);\n",
"\n",
" var y = d3.scale.linear()\n",
" .range([height, 0]);\n",
"\n",
" var color = d3.scale.category10();\n",
"\n",
" var xAxis = d3.svg.axis()\n",
" .scale(x)\n",
" .orient(\"bottom\");\n",
"\n",
" var yAxis = d3.svg.axis()\n",
" .scale(y)\n",
" .orient(\"left\");\n",
"\n",
" var svg = d3.select(\"#scatterplot\").append(\"svg\")\n",
" .attr(\"width\", width + margin.left + margin.right)\n",
" .attr(\"height\", height + margin.top + margin.bottom)\n",
" .append(\"g\")\n",
" .attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\n",
"\n",
" var tooltip = d3.select(\"body\").append(\"div\")\n",
" .attr(\"class\", \"tooltip\")\n",
" .style(\"opacity\", 0);\n",
"\n",
" x.domain([0, d3.extent(window.vizObj, function(d) {return d.age})[1]]);\n",
" y.domain([0, d3.extent(window.vizObj, function(d) {return d.height})[1]]);\n",
"\n",
" svg.append(\"g\")\n",
" .attr(\"class\", \"x axis\")\n",
" .attr(\"transform\", \"translate(0,\" + height + \")\")\n",
" .call(xAxis)\n",
" .append(\"text\")\n",
" .attr(\"class\", \"label\")\n",
" .attr(\"x\", width)\n",
" .attr(\"y\", -6)\n",
" .style(\"text-anchor\", \"end\")\n",
" .text(\"Age\");\n",
"\n",
" svg.append(\"g\")\n",
" .attr(\"class\", \"y axis\")\n",
" .call(yAxis)\n",
" .append(\"text\")\n",
" .attr(\"class\", \"label\")\n",
" .attr(\"transform\", \"rotate(-90)\")\n",
" .attr(\"y\", 6)\n",
" .attr(\"dy\", \".71em\")\n",
" .style(\"text-anchor\", \"end\")\n",
" .text(\"Height (cm)\");\n",
"\n",
" svg.selectAll(\"circle\")\n",
" .data(window.vizObj)\n",
" .enter().append(\"circle\")\n",
" .attr(\"r\", function(d) {return (d.weight - 30)/ 5})\n",
" .attr(\"cx\", function(d) { return x(d.age); })\n",
" .attr(\"cy\", function(d) { return y(d.height); })\n",
" .attr(\"fill\", function(d) {if (d.sex == \"male\") {return \"#3182bd\"} else {return \"#ef3b2c\"}})\n",
" .attr(\"opacity\", .6)\n",
" .attr(\"stroke\", \"black\")\n",
" .attr(\"stroke-width\", 0)\n",
" .on(\"mouseover\", function(d) {\n",
" d3.select(this).attr(\"opacity\", 1).attr(\"stroke-width\", 1);\n",
" tooltip.transition()\n",
" .duration(100)\n",
" .style(\"opacity\", .9);\n",
" tooltip.html(d.name + \"<br/> (\" + d.age + \": \" + d.height + \"cm)\")\n",
" .style(\"left\", (d3.event.pageX + 15) + \"px\")\n",
" .style(\"top\", (d3.event.pageY + 10) + \"px\");\n",
" })\n",
" .on(\"mouseout\", function(d) {\n",
" d3.select(this).attr(\"opacity\", .6).attr(\"stroke-width\", 0);\n",
" tooltip.transition()\n",
" .duration(500)\n",
" .style(\"opacity\", 0);\n",
" });\n",
"};\n",
"window.plotit = plotit;"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div id=\"scatterplot\"></div>\n",
"<script type=\"text/javascript\">window.plotit();</script>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<div id=\"scatterplot\"></div>\n",
"<script type=\"text/javascript\">window.plotit();</script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As mentioned before, now that you know how to insert external JavaScript libraries in your notebook, move data from Python to JavaScript and interact with the DOM of your notebook, you can use this principle for other JavaScript libraries too.\n",
"\n",
"## CartoDB\n",
"\n",
"Let's add a dummy CartoDB visualization."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<link rel=\"stylesheet\" href=\"http://libs.cartocdn.com/cartodb.js/v3/3.15/themes/css/cartodb.css\" />\n",
"<style>\n",
"#map {\n",
" height: 100%;\n",
" padding: 0;\n",
" margin: 0;\n",
"}\n",
"</style>\n",
"<script src=\"http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js\"></script>\n",
"<div id=\"map\" style=\"height: 400px; width:600px;\"></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%html\n",
"<link rel=\"stylesheet\" href=\"http://libs.cartocdn.com/cartodb.js/v3/3.15/themes/css/cartodb.css\" />\n",
"<style>\n",
"#map {\n",
" height: 100%;\n",
" padding: 0;\n",
" margin: 0;\n",
"}\n",
"</style>\n",
"<script src=\"http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js\"></script>\n",
"<div id=\"map\" style=\"height: 400px; width:600px;\"></div>"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"cartodb.createVis('map', 'http://documentation.cartodb.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json', {\n",
" shareable: true,\n",
" title: true,\n",
" description: true,\n",
" search: true,\n",
" tiles_loader: true,\n",
" center_lat: 0,\n",
" center_lon: 0,\n",
" zoom: 2\n",
" })\n",
" .done(function(vis, layers) {\n",
" // layer 0 is the base layer, layer 1 is cartodb layer\n",
" // setInteraction is disabled by default\n",
" layers[1].setInteraction(true);\n",
" layers[1].on('featureOver', function(e, latlng, pos, data) {\n",
" cartodb.log.log(e, latlng, pos, data);\n",
" });\n",
" // you can get the native map to work with it\n",
" var map = vis.getNativeMap();\n",
" // now, perform any operations you need\n",
" // map.setZoom(3);\n",
" // map.panTo([50.5, 30.5]);\n",
" })\n",
" .error(function(err) {\n",
" console.log(err);\n",
" });"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"cartodb.createVis('map', 'http://documentation.cartodb.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json', {\n",
" shareable: true,\n",
" title: true,\n",
" description: true,\n",
" search: true,\n",
" tiles_loader: true,\n",
" center_lat: 0,\n",
" center_lon: 0,\n",
" zoom: 2\n",
" })\n",
" .done(function(vis, layers) {\n",
" // layer 0 is the base layer, layer 1 is cartodb layer\n",
" // setInteraction is disabled by default\n",
" layers[1].setInteraction(true);\n",
" layers[1].on('featureOver', function(e, latlng, pos, data) {\n",
" cartodb.log.log(e, latlng, pos, data);\n",
" });\n",
" // you can get the native map to work with it\n",
" var map = vis.getNativeMap();\n",
" // now, perform any operations you need\n",
" // map.setZoom(3);\n",
" // map.panTo([50.5, 30.5]);\n",
" })\n",
" .error(function(err) {\n",
" console.log(err);\n",
" });"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ok, you could achieve similar results with something like [Folium](https://folium.readthedocs.org/en/latest/) that will render leaflet maps using Python data. But really, why do it high level if you can do it low level?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Data tables\n",
"\n",
"Don't like the standard way Jupyter displays the data in your data frames? Why not use the [dataTables](https://datatables.net/) library?\n",
"\n",
"The dataTables library is a jQuery plugin. The notebook already uses jQuery, so we'll have to hook the plugin onto that jQuery version. We'll have to be more careful here:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"require.config({\n",
" paths: {\n",
" datatables: '//cdn.datatables.net/1.10.11/js/jquery.dataTables.min'\n",
" }\n",
"});"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"require.config({\n",
" paths: {\n",
" datatables: '//cdn.datatables.net/1.10.11/js/jquery.dataTables.min'\n",
" }\n",
"});"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>age</th>\n",
" <th>height</th>\n",
" <th>name</th>\n",
" <th>sex</th>\n",
" <th>weight</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>28</td>\n",
" <td>185</td>\n",
" <td>Jan</td>\n",
" <td>male</td>\n",
" <td>84</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>34</td>\n",
" <td>177</td>\n",
" <td>Piet</td>\n",
" <td>male</td>\n",
" <td>82</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>22</td>\n",
" <td>180</td>\n",
" <td>Joris</td>\n",
" <td>male</td>\n",
" <td>78</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>42</td>\n",
" <td>172</td>\n",
" <td>Korneel</td>\n",
" <td>male</td>\n",
" <td>81</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>12</td>\n",
" <td>157</td>\n",
" <td>Lisa</td>\n",
" <td>female</td>\n",
" <td>48</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" age height name sex weight\n",
"0 28 185 Jan male 84\n",
"1 34 177 Piet male 82\n",
"2 22 180 Joris male 78\n",
"3 42 172 Korneel male 81\n",
"4 12 157 Lisa female 48"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"console.log(\"off we go!\");\n",
"$('.dataframe').DataTable();"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%javascript\n",
"console.log(\"off we go!\");\n",
"$('.dataframe').DataTable();\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"This is not working yet. I've commented on [this issue](https://github.com/jupyter/notebook/issues/749) as I'm probably still loading the DataTables library the wrong way."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment