Using D3.js in Jupyter notebook
In [1]:
csvstring = """
Time;BTC;DOGE;ETH;LTC;REP
2017-05-03 23:17;19,70;;78,88;20,81;
2017-05-04 20:18;21,21;;90,45;24,91;
2017-05-05 19:11;20,1;11,58;91,73;24,06;
2017-05-06 18:56;20,28;12,37;92,78;25,91;
2017-05-09 0:50;21,77;20,34;89,27;28,45;
2017-05-09 2:15;21,99;20,58;88,62;28,49;34,70
2017-05-09 23:59;22,46;17,51;87,45;30,14;32,45
2017-05-11 0:57;23,15;18,83;86,94;32,18;34,36
2017-05-11 22:17;24,17;17,48;87,87;29,62;34,36
2017-05-12 1:55;24,13;17,99;88,05;30,02;36,08
2017-05-13 1:57;22,41;17,48;85,25;27,00;33,72
2017-05-14 15:32;23,67;17,04;89,19;28,90;34,24
2017-05-14 23:34;23,47;17,51;88,60;28,01;33,72
2017-05-15 22:12;22,34;16,16;90,20;24,43;32,58
2017-05-16 20:25;23,12;15,68;88,54;24,19;31,36
2017-05-17 22:01;24,00;19,26;86,28;24,50;30,62
2017-05-18 23:45;24,84;21,05;94,93;27,93;32,62
2017-05-19 22:01;25,59;21,98;118,55;27,03;33,62"""
Write the CSV text fo a file.
In [2]:
!echo "$csvstring" > wallet.csv
Check if the file exists.
In [3]:
!ls -la wallet.csv
Check the last entry of the CSV file.
In [4]:
!tail -n 1 wallet.csv
Read the file into a dataframe.
In [5]:
import pandas as pd
wallet_data = pd.read_csv('wallet.csv', sep=';', decimal=",")
wallet_data = wallet_data.fillna(0)
wallet_data.head()
Out[5]:
Add a total column for the currency columns.
In [6]:
wallet_data['total'] = wallet_data.ix[:, wallet_data.columns != 'Time'].sum(axis=1)
In [7]:
wallet_data
Out[7]:
Convert the data to a dictionary that Javascript can use.
In [8]:
wallet_data = wallet_data.to_json(orient='records')
Attach the data to the current window by using Javascript.
In [9]:
from IPython.display import Javascript
Javascript("""
window.walletData={};
""".format(wallet_data))
Out[9]:
Create the graph¶
First include the D3.js library.
In [1]:
%%javascript
require.config({
paths: {
d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min'
}
});
I copied the content of my gist to recreate the graph inside this notebook. Use the HTML function of IPython to attach inline style to the page.
In [11]:
from IPython.core.display import HTML
HTML("""
<style>
path {
stroke-width: 1;
fill: none;
stroke-linejoin: round;
stroke-linecap: round;
}
circle {
stroke-width: 1;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.legend, .label, .hover-text{
font-size: x-small;
background-color: white;
}
</style>
""")
Out[11]:
Create the graph by retrieving the data from the window.
In [12]:
%%javascript
require(['d3'], function(d3) {
//a weird idempotency thing
$("#chart1").remove();
//create canvas
element.append("<svg id='chart1' width='960' height='500'></svg>");
var svg = d3.select('svg'),
margin = {
top: 20,
right: 50,
bottom: 100,
left: 50
},
width = +svg.attr('width') - margin.left - margin.right,
height = +svg.attr('height') - margin.top - margin.bottom,
g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Graph title
g.append('text')
.attr('x', (width / 2))
.attr('y', 0 - (margin.top / 3))
.attr('text-anchor', 'middle')
.style('font-size', '16px')
.text('Wallet chart');
// Function to convert a string into a time
var parseTime = d3.time.format('%Y-%m-%d %H:%M').parse;
// Function to show specific time format
var formatTime = d3.time.format('%e %B');
// Set data
var data = window.walletData;
data.forEach(function(d) {
d.date = parseTime(d.Time);
});
// Set the X scale
var x = d3.time.scale().range([0, width], 0.5);
// Set the Y scale
var y = d3.scale.linear().range([height, 0]);
// Set the color scale
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
// .interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.worth);
});
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "Time" && key !== "date";
}));
var currencies = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
date: d.date,
worth: +d[name]
};
})
};
});
x.domain(d3.extent(data, function(d) {
return d.date;
}));
// Set the Y domain
y.domain([
d3.min(currencies, function(c) {
return d3.min(c.values, function(v) {
return v.worth;
});
}),
d3.max(currencies, function(c) {
return d3.max(c.values, function(v) {
return v.worth;
});
})
]);
// Set the X axis
g.append("g")
.attr("class", "x axis")
// .attr("fill", "none")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Set the Y axis
g.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Value (USD)");
// Draw the lines
var currency = g.selectAll(".currency")
.data(currencies)
.enter().append("g")
.attr("class", "currency");
currency.append("path")
.attr("class", "line")
.attr("fill", "none")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name);
});
// Add the circles
currency.append("g").selectAll("circle")
.data(function(d) {
return d.values
})
.enter()
.append("circle")
.attr("r", 2)
.attr("cx", function(dd) {
return x(dd.date)
})
.attr("cy", function(dd) {
return y(dd.worth)
})
.attr("fill", "none")
.attr("stroke", function(d) {
return color(this.parentNode.__data__.name)
});
// Add label to the end of the line
currency.append("text")
.attr("class", "label")
.datum(function(d) {
return {
name: d.name,
value: d.values[d.values.length - 1]
};
})
.attr("transform", function(d) {
return "translate(" + x(d.value.date) + "," + y(d.value.worth) + ")";
})
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) {
return d.name;
});
});
In [ ]: