Public
Edited
Apr 11, 2024
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = FileAttachment("probly.csv").csv({tyed: true})
Insert cell
// Get the different categories and count them
categories = data.columns
Insert cell
n = categories.length
Insert cell
Insert cell
height = 500
Insert cell
margin = ({
top: 60,
right: 30,
bottom: 20,
left:110
})
Insert cell
Insert cell
// Add X axis
x = d3.scaleLinear()
.domain([-10, 140])
.range([margin.left, width - margin.right]);
Insert cell
y = d3.scaleLinear()
.domain([0, 0.4])
.range([height - margin.bottom, margin.top]);
Insert cell
// Create the Y axis for names
yName = d3.scaleBand()
.domain(categories)
.range([0, height - margin.bottom])
.paddingInner(1)
Insert cell
Insert cell
SVGcontainer = {

// append the svg object to the body of the page
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height + 150)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;")

const xAxis = svg.append("g")
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x));
const yAxis = svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(yName));

return svg.node();
}
Insert cell
Insert cell
chart = {

// append the svg object to the body of the page
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height + 150)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;")

const xAxis = svg.append("g")
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x));
const yAxis = svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(yName));

// Compute kernel density estimation for each column:
const kde = kernelDensityEstimator(kernelEpanechnikov(7), x.ticks(40)) // increase this 40 for more accurate density.
const allDensity = []
for (let i = 0; i < n; i++) {
let key = categories[i]
let density = kde( data.map(function(d){ return d[key]; }) )
allDensity.push({key: key, density: density})
}

// Add areas
const area = svg.selectAll("areas")
.data(allDensity)
.join("path")
.attr("transform", function(d){return(`translate(0, ${(yName(d.key) - height + margin.bottom)})`)})
.datum(function(d){return(d.density)})
.attr("fill", "#47A8BD")
.attr("stroke", "#000")
.attr("stroke-width", 1)
.attr("d", d3.line()
.curve(d3.curveBasis)
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); })
)

// 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;
};
}
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
import {toc} from "@jonfroehlich/collapsible-toc"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more