import pandas as pd
import jinja2
from IPython.display import display, Javascript, HTML
You may need to adjust the *height* depending on your output.
def inline_dc(stuff):
"""
Embeds the HTML source of the dc charts directly into the IPython notebook.
This method will not work if the dc charts depends on any files (json data). Also this uses
the HTML5 srcdoc attribute, which may not be supported in all browsers.
"""
return HTML('<iframe srcdoc="{srcdoc}" style="width: 100%; height: 300px; border: none"></iframe>'.format(srcdoc=stuff.replace('"', '"')))
These may need to be updated as they rely on third party links
head = HTML("""
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.0.0-alpha.2/dc.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.9/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.0/dc.min.js"></script>
</head>
""")
body_html = HTML("""
<!-- A div anchor that can be identified by id -->
<div id="bubblechart" class="dc-chart">
<!-- Title or anything you want to add above the chart -->
<strong>Bubble Chart</strong>
<!--
This will create a reset button when ever the user selects a filter.
Clicking on the reset button will remove all filters.
-->
<a class="reset" href="javascript:BubbleChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
<!--
dc.js will also automatically inject applied current filter value into
any html element with css class set to "filter"
-->
<span class="reset" style="display: none;">Current filter: <span class="filter"></span></span>
<br>
</br>
</div>
""")
df = pd.DataFrame({'population':[234,345,345,34],
'age':[2,2,6,9],
'state':['a','b','c','d'],
'state2':['d','c','b','a']})
df
age | population | state | state2 | |
---|---|---|---|---|
0 | 2 | 234 | a | d |
1 | 2 | 345 | b | c |
2 | 6 | 345 | c | b |
3 | 9 | 34 | d | a |
dc = jinja2.Template(
"""
// Create Global Variables
var BubbleChart = dc.bubbleChart("#bubblechart");
// Load data
var dataset = {{ data }};
// Call function
Graph(dataset);
// Create function
function Graph(data) {
// Feed it through crossfilter
var ndx = crossfilter(data);
// for testing
console.log(data);
//define a dimension
//Here we will group by age
var dim = ndx.dimension(function(d) {return d.age});
//Here we group by age and do a bunch of stuff
var g = dim.group().reduce(
//add
function(p,v) {
++p.count;
p.sumIndex +=v.age;
p.avgIndex=p.sumIndex/p.count;
return p;
},
//remove
function(p,v) {
--p.count;
p.sumIndex -=v.age;
p.avgIndex=p.sumIndex/p.count;
return p;
},
//init
function() {
return {count:0, sumIndex:0,
avgIndex:0 };
}
);
//max number of group
var maxDomain = d3.max(g.all(), function(d) { return d.value.sumIndex; }) + 1;
//Lets create a bubble chart
BubbleChart.dimension(dim)
.width(500)
.height(200)
.group(g)
.valueAccessor(function(p) {return p.value.sumIndex;}) // retrieve y value from multi-value group
.radiusValueAccessor(function(p) {return p.value.sumIndex;})
.x(d3.scale.linear().domain([0,maxDomain]).range([0,20]))
.y(d3.scale.linear().domain([0,maxDomain]).range([0,20]))
.r(d3.scale.linear().domain([0, 4000]))
.title(function (p) {
return [
"count: " + p.value.count,
"sumIndex: " + p.value.sumIndex,
"avgIndex: " + p.value.avgIndex,
]
.join("\\n");
})
.renderTitle(true)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true);
dc.renderAll(); // render all charts on the page
}; // end graph function
""")
body_js = Javascript(dc.render(
data=df.to_json(orient='records')
))
inline_dc(head.data + body_html.data + "<script>" + body_js.data + "</script>")
Author: David Rojas LLC