Public
Edited
Apr 27, 2023
Insert cell
Insert cell
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js"

Insert cell
simpleStatistics = require("simple-statistics@7")
Insert cell
async function fetchIrisData() {
const url = "https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv";
const data = await d3.csv(url, d3.autoType);
return data;
}
Insert cell
dataset = fetchIrisData();
Insert cell
width = 900;
Insert cell
height = 400;
Insert cell
margin = ({top: 20, right: 20, bottom: 30, left: 40});
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.sepal_length))
.range([margin.left, width - margin.right]);
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(dataset, d => d.sepal_width))
.range([height - margin.bottom, margin.top]);
Insert cell
color = d3.scaleOrdinal()
.domain(dataset.map(d => d.species))
.range(d3.schemeCategory10);
Insert cell
size = d3.scaleSqrt()
.domain([0, d3.max(dataset, d => d.sepal_length)])
.range([0, 20]);
Insert cell
xGridlines = d3.axisBottom(x)
.tickSize(-height + margin.top + margin.bottom)
.tickFormat('');
Insert cell
yGridlines = d3.axisLeft(y)
.tickSize(-width + margin.left + margin.right)
.tickFormat('');
Insert cell
svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
Insert cell
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x))
.append("text")
.attr("x", width - margin.right)
.attr("y", -6)
.attr("fill", "currentColor")
.attr("font-weight", "bold")
.attr("text-anchor", "end")
.text("Sepal Length (cm)");
Insert cell
svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.append("text")
.attr("x", -margin.left)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text("Sepal Width (cm)");
Insert cell
legend = svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("g")
.data(color.domain().slice().reverse())
.join("g")
.attr("transform", (d, i) => `translate(0,${i * 20})`);
Insert cell
legend.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", color);
Insert cell
legend.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.35em")
.text(d => d);
Insert cell
annotations = [
{ species: "setosa", sepal_length: 4.9, sepal_width: 3.1 },
{ species: "versicolor", sepal_length: 7, sepal_width: 3.2 },
{ species: "virginica", sepal_length: 7.7, sepal_width: 2.8 }
];
Insert cell
svg.selectAll(".annotation")
.data(annotations)
.join("text")
.attr("class", "annotation")
.attr("x", d => x(d.sepal_length))
.attr("y", d => y(d.sepal_width))
.attr("dx", 15)
.attr("dy", 15)
.text(d => d.species);
Insert cell
svg.selectAll("circle")
.data(dataset)
.join("circle")
.attr("cx", d => x(d.sepal_length))
.attr("cy", d => y(d.sepal_width))
.attr("r", d => size(d.sepal_length))
.attr("fill", d => color(d.species))
.attr("stroke", "black");
Insert cell
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x));
Insert cell
svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y));
Insert cell
trendlineData = dataset.map(d => [d.sepal_length, d.sepal_width]);
Insert cell
linearRegression = simpleStatistics.linearRegression(trendlineData);
Insert cell
linearRegressionLine = simpleStatistics.linearRegressionLine(linearRegression);
Insert cell
function addTrendline(svg, x, y, data) {
const trendlineData = data.map(d => [d.sepal_length, d.sepal_width]);
const linearRegression = simpleStatistics.linearRegression(trendlineData);
const linearRegressionLine = simpleStatistics.linearRegressionLine(linearRegression);

const xSeries = data.map(d => d.sepal_length);
const xMin = simpleStatistics.min(xSeries);
const xMax = simpleStatistics.max(xSeries);

const y1 = linearRegressionLine(xMin);
const y2 = linearRegressionLine(xMax);

svg.append("line")
.attr("x1", x(xMin))
.attr("y1", y(y1))
.attr("x2", x(xMax))
.attr("y2", y(y2))
.attr("stroke", "red")
.attr("stroke-width", 2);
}
Insert cell
svg //addTrendline(svg, x, y, dataset); ?
Insert cell
svg.node();
Insert cell
//Annotation: I am not sure why but my labels didn't move. I tried lots of different things and went through multiple online forums to discover my mistake. same goes for the plotting of the linear regression. I think that it is correctly defined, but nothing is visualized
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