Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<style>
/* .y-axis text, .x-axis text {
fill: white;
opacity: .85;
}
.y-axis line, .y-axis path { opacity: 0}
.x-axis line, .x-axis path {
stroke: white;
opacity: .85;
} */
.y-axis, .x-axis {
font-family: 'arial'
}
</style>
</head>
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- Create a div where the graph will take place -->
<body></body>
<!-- <script src="joyplot.js"></script> -->
<script>
// set the dimensions and margins of the graph
var margin = {top: 120, right: 30, bottom: 20, left:110},
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style('background-color', 'white')
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
//read data
d3.csv("https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv", function(data) {
// Get the different categories and count them
var categories = data.columns.filter(d => !isNaN(data[0][d]))
var n = categories.length
const {min, max} = csvExtent(data)
// Add X axis
var x = d3.scaleLinear()
.domain([min - 15, max + 15])
.range([ 0, width ]);
svg.append("g")
.attr('class', 'x-axis')
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Create a Y scale for densities
var y = d3.scaleLinear()
.domain([0, .25])
.range([ height, 0]);
// Create the Y axis for names
var yName = d3.scaleBand()
.domain(categories)
.range([0, height])
.paddingInner(1)
svg.append("g")
.attr('class', 'y-axis')
.call(d3.axisLeft(yName));
// Compute kernel density estimation for each column:
var kde = kernelDensityEstimator(kernelEpanechnikov(7), x.ticks(40)) // increase this 40 for more accurate density.
var allDensity = []
for (i = 0; i < n; i++) {
key = categories[i]
density = kde( data.map(function(d){ return d[key]; }) )
allDensity.push({key: key, density: density})
}
// Add areas
svg.selectAll("areas")
.data(allDensity)
.enter()
.append("path")
.attr("transform", function(d){return("translate(0," + (yName(d.key)-height) +")" )})
.datum(d => d.density)
.attr("fill", "skyblue")
.attr('opacity', 1)
.attr("stroke", "azure")
.attr("stroke-width", 1)
.attr("d", d3.line()
.curve(d3.curveStep)
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); })
)
}) // end csv load
// This is what I need to compute kernel density estimation
function kernelDensityEstimator(kernel, X) {
return function(V) {
return X.map(function(x) {
return [x, d3.mean(V, function(v) { return kernel(x - v); })];
});
};
}
function kernelEpanechnikov(k) {
return function(v) {
return Math.abs(v /= k) <= 1 ? 0.75 * (1 - v * v) / k : 0;
};
}
function csvExtent(data) {
const colNames = data.columns
const extents = colNames.map(col => d3.extent(data, d => +d[col]));
const csvMin = d3.min(extents, d => d[0])
const csvMax = d3.max(extents, d => d[1])
return {'min': csvMin, 'max': csvMax}
}
</script>
https://d3js.org/d3.v4.js