Public
Edited
Apr 27, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
wineQuality = winequality
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const width = canvasWidth;
const height = canvasHeight;
const svg = DOM.svg(width, height);
svg.setAttribute('class', 'scatter-plot');

const labels = {
Alcohol: "Alcohol (%)",
"Citric Acid": "Posición Ideológica Estimada"
};
const paddings = {};

scatterPlot({
width,
height,
chart: d3.select(svg),
data: wineQuality,
xfield: xVar,
xlabel: labels[xVar] || xVar,
yfield: yVar,
ylabel: labels[yVar] || yVar,
xgrid: true,
ygrid: true,
ypadding: paddings[yVar],
xpadding: paddings[xVar],
colorField: "Quality",
size:2,
title: "Partidos"
});

return svg;
}
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require("d3@5")
Insert cell
function scatterPlot({
chart,
width,
height,
data,
xfield,
yfield,
xpadding,
ypadding,
colorField,
size,
title,
xlabel,
ylabel,
xgrid,
ygrid
}) {
let topPadding = titleHeight + figPadding;
let leftPadding = figPadding + yAxisWidth;
let bottomPadding = figPadding + xAxisHeight;
let svg = chart.node();
let w = width - leftPadding - figPadding - 1;
let h = height - topPadding - bottomPadding;

let x = linearScale(data, xfield, [0, w], xpadding);
let y = linearScale(data, yfield, [h, 0], ypadding);

// Add x axis
let xAxis = d3
.axisBottom(x)
.tickPadding(4)
.tickSizeOuter(0);
chart
.append("g")
.attr("class", "x axis")
.attr(
"transform",
"translate(" + leftPadding + "," + (h + topPadding) + ")"
)
.call(xAxis);

// Add x axis label
chart
.append("text")
.attr(
"transform",
"translate(" + (leftPadding + w / 2) + " ," + (height - figPadding) + ")"
)
.style("text-anchor", "middle")
.text(xlabel);

// x axis
// Ref: https://bl.ocks.org/d3noob/c506ac45617cf9ed39337f99f8511218
if (xgrid) {
chart
.append("g")
.attr("class", "x grid")
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")")
.call(
xAxis
.tickSize(h)
.tickFormat("")
.ticks(5)
);
}

// Add y axis
let yAxis = d3
.axisLeft(y)
.tickSizeOuter(0)
//.ticks(4);
chart
.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")")

// Add y axis label
chart
.append("text")
.attr(
"transform",
"rotate(-90)," +
"translate(" +
(0 - topPadding - h / 2) +
" ," +
(figPadding + textHeight / 2) +
")"
)
.style("text-anchor", "middle")
//.text(ylabel);

// y grid
if (ygrid) {
chart
.append("g")
.attr("class", "y grid")
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")")
.call(yAxis.tickSize(-w).tickFormat(""));
}

// create a new group, use `selectAll` to build an empty
// list context
let dots = chart
.append("g")
.attr("class", "dots")
.selectAll()
.data(data)
.enter()
.append("circle")
.attr("cx", d => leftPadding + x(d[xfield]))
.attr("cy", d => topPadding + y(d[yfield]))
.attr("r", size);

// add Legend
if (colorField) {
let color = d3.scaleOrdinal(d3.schemeSet2);
color.domain(pointScale(data, colorField).domain());

// Or single color?
// let color = d3.scaleOrdinal(d3.schemeReds[9].slice(3))
// color.domain(pointScale(data, colorField).domain())

dots = dots.attr("fill", d => color(d[colorField]));

// draw legend
let legend = chart
.append("g")
.attr("class", "legend")
.attr(
"transform",
"translate(" + (leftPadding + w - 97) + "," + (topPadding + 20) + ")"
);
}

// Add title
chart
.append("text")
.attr("class", "title")
.attr("text-anchor", "middle")
.attr("x", w / 2 + leftPadding)
.attr("y", figPadding + titleHeight / 2)
.text(title);

return chart;
}
Insert cell
/**
* Create linear scale from the values of some field.
* Always maps to a 0 to X range so it can be used to
* generate actual coordinates on the plotting canvas.
*/
function linearScale(data, field, range, padding) {
const vals = data.map(d => d[field]);
const minVal = d3.min(vals);
const maxVal = d3.max(vals);
// Use `padding` to add some spaces between min max
// by default add 3% on both sides
const width = maxVal - minVal;
const pad = padding
? padding
: [x => x - 0.03 * width, x => x + 0.03 * width];
const mi = applyPadding(minVal, pad[0]);
const ma = applyPadding(maxVal, pad[1]);
return d3
.scaleLinear()
.domain([mi, ma])
.range(range);
}
Insert cell
function applyPadding(x, ratio) {
if (typeof ratio == "function") {
return ratio(x);
}
return x * ratio;
}
Insert cell
Insert cell
wineQuality.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

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