{"id":"b7775f8549afff6b","slug":"kernel-density-estimation","trashed":false,"description":"","likes":43,"publish_level":"live","forks":42,"fork_of":null,"has_importers":true,"update_time":"2024-10-07T08:36:52.439Z","first_public_version":168,"paused_version":null,"publish_time":"2023-07-17T08:24:59.798Z","publish_version":223,"latest_version":223,"thumbnail":"5c76a40bfd7202700be8c974b5a0ce20fe33097ef6fc0c2db3a37487117b32e7","default_thumbnail":"5c76a40bfd7202700be8c974b5a0ce20fe33097ef6fc0c2db3a37487117b32e7","roles":[],"sharing":null,"owner":{"id":"863951e3ebe4c0ae","avatar_url":"https://avatars.observableusercontent.com/avatar/5af16e327a90b2873351dda8a596c0d2d3bf954f64523deefe80177c9764d0f7","login":"d3","name":"D3","bio":"Bring your data to life.","home_url":"https://d3js.org","type":"team","tier":"pro_2024"},"creator":{"id":"074c414ad1d825f5","avatar_url":"https://avatars.observableusercontent.com/avatar/82811927da99f8938001b2ef1f552ad2c47083e46ebc55a3a146a5a5848c4519","login":"mbostock","name":"Mike Bostock","bio":"Visualization toolmaker. Founder @observablehq. Creator @d3. Former @nytgraphics. Pronounced BOSS-tock.","home_url":"https://bost.ocks.org/mike/","tier":"pro"},"authors":[{"id":"074c414ad1d825f5","avatar_url":"https://avatars.observableusercontent.com/avatar/82811927da99f8938001b2ef1f552ad2c47083e46ebc55a3a146a5a5848c4519","name":"Mike Bostock","login":"mbostock","bio":"Visualization toolmaker. Founder @observablehq. Creator @d3. Former @nytgraphics. Pronounced BOSS-tock.","home_url":"https://bost.ocks.org/mike/","tier":"pro","approved":true,"description":""}],"collections":[{"id":"1b0fbc3b1939d7fa","type":"public","slug":"gallery","title":"Gallery","description":"Examples featured in the D3 gallery","update_time":"2023-04-10T02:28:10.124Z","pinned":false,"ordered":false,"custom_thumbnail":null,"default_thumbnail":"6953adf7aec9d29339751fa68d9c9dc67169a0ffd7469f9a4055eda920bdd2a4","thumbnail":"6953adf7aec9d29339751fa68d9c9dc67169a0ffd7469f9a4055eda920bdd2a4","listing_count":147,"parent_collection_count":0,"owner":{"id":"863951e3ebe4c0ae","avatar_url":"https://avatars.observableusercontent.com/avatar/5af16e327a90b2873351dda8a596c0d2d3bf954f64523deefe80177c9764d0f7","login":"d3","name":"D3","bio":"Bring your data to life.","home_url":"https://d3js.org","type":"team","tier":"pro_2024"}}],"files":[{"id":"0e03c99b37791436e0cb486d09934b5aa6b6e000947328a81817caba4c5abf1e06276e260f42d089b9067e3e5cdd1a88c441c7193bbadc8b3a07503fd14bd7d7","url":"https://static.observableusercontent.com/files/0e03c99b37791436e0cb486d09934b5aa6b6e000947328a81817caba4c5abf1e06276e260f42d089b9067e3e5cdd1a88c441c7193bbadc8b3a07503fd14bd7d7","download_url":"https://static.observableusercontent.com/files/0e03c99b37791436e0cb486d09934b5aa6b6e000947328a81817caba4c5abf1e06276e260f42d089b9067e3e5cdd1a88c441c7193bbadc8b3a07503fd14bd7d7?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27faithful.json","name":"faithful.json","create_time":"2019-10-30T00:06:21.033Z","mime_type":"application/json","status":"public","size":818,"content_encoding":"gzip","private_bucket_id":null}],"comments":[{"id":"4e52bf92deb3ac58","content":"Since bandwidth is a featured adjustable parameter in this notebook, would it make sense to have the number of thresholds (currently set to 40 in this cell) depend on the bandwidth?  Perhaps something like numThresholds = dataRange / bandwidth, where dataRange = d3.max(data) - d3.min(data)?  \n\nMy intuition is that when plotting in the wild, the situation could be reversed:  one could fix the number of thresholds at 40 and then let bandwidth = dataRange / numThresholds.","node_id":54,"create_time":"2021-10-07T15:31:34.743Z","update_time":null,"resolved":true,"user":{"id":"2f8eb6f7ed4c3631","avatar_url":"https://avatars.observableusercontent.com/avatar/2b1c8f8435d8a2484d0fdd54b8e57f2d9a1c01c94b3bc5a8433833e6a16bae46","login":"jameshenegan","name":"Jim Henegan","bio":"","home_url":"","tier":"public"}}],"commenting_lock":null,"suggestion_from":null,"suggestions_to":[],"version":223,"title":"Kernel density estimation","license":"isc","copyright":"Copyright 2019–2023 Observable, Inc.","nodes":[{"id":0,"value":"<div style=\"color: grey; font: 13px/25.5px var(--sans-serif); text-transform: uppercase;\"><h1 style=\"display: none;\">Kernel density estimation</h1><a href=\"https://d3js.org/\">D3</a> › <a href=\"/@d3/gallery\">Gallery</a></div>\n\n# Kernel density estimation\n\n[KDE](https://en.wikipedia.org/wiki/Kernel_density_estimation) estimates the probability distribution of a random variable. The kernel’s *bandwidth* determines the estimate’s smoothness: if the bandwidth is too small, the estimate may include spurious bumps and wiggles; too large, and the estimate reveals little about the underlying distribution.\n\nThis example, based on [work by John Firebaugh](https://bl.ocks.org/jfirebaugh/900762), shows times between eruptions of [Old Faithful](https://en.wikipedia.org/wiki/Old_Faithful). See also a [two-dimensional density estimation](/@d3/density-contours) of this data.","pinned":false,"mode":"md","data":{},"name":""},{"id":65,"value":"viewof bandwidth = Inputs.range([1, 20], {value: 7, step: 0.1, label: \"Bandwidth\"})","pinned":false,"mode":"js","data":null,"name":null},{"id":177,"value":"// For the sake of simplicity, use Plot to draw the output; for the equivalent D3 chart, see\n// https://observablehq.com/@d3/kernel-density-estimation@172\nchart = Plot.plot({\n  width: 928,\n  height: 500,\n  x: {label: \"Time between eruptions (min.)\"},\n  y: {label: null, tickFormat: \"%\", grid: true},\n  marks: [\n    Plot.rectY(data, Plot.binX({y: \"proportion\"}, {thresholds, fill: \"#bbb\"})),\n    Plot.ruleY([0]),\n    Plot.line(density, {curve: \"basis\"})\n  ]\n})","pinned":false,"mode":"js","data":null,"name":null},{"id":54,"value":"thresholds = d3.ticks(...d3.nice(...d3.extent(data), 10), 40)","pinned":true,"mode":"js","data":null,"name":null},{"id":9,"value":"function kde(kernel, thresholds, data) {\n  return thresholds.map(t => [t, d3.mean(data, d => kernel(t - d))]);\n}","pinned":true,"mode":"js","data":{"display":{"mode":"none"}},"name":null},{"id":11,"value":"function epanechnikov(bandwidth) {\n  return x => Math.abs(x /= bandwidth) <= 1 ? 0.75 * (1 - x * x) / bandwidth : 0;\n}","pinned":true,"mode":"js","data":{"display":{"mode":"none"}},"name":null},{"id":30,"value":"density = kde(epanechnikov(bandwidth), thresholds, data)","pinned":true,"mode":"js","data":null,"name":null},{"id":5,"value":"data = FileAttachment(\"faithful.json\").json()","pinned":true,"mode":"js","data":null,"name":null}],"resolutions":[],"schedule":null,"last_view_time":null}