Public
Edited
Jan 7, 2021
Insert cell
Insert cell
Insert cell
vl
.markPoint({ filled: true, size: 100 }) //filled: true,
.data(sicily) //.filter(d => new Date(d.date) > new Date(2005, 0, 9)))
//.transform(vl.regression('rate').on('date')).markLine()
.encode(
vl
.x() //{ timeUnit: 'month-year' }
.fieldT('date')
.timeUnit('yearmonth')
.axis({ grid: false, format: '%b-%y' }) //tickCount: 4
.title('Year'),
vl
.y()
.fieldQ('rate')
.scale({ domain: [150, 300] }) //{ zero: false }
.axis({ grid: false })
.title('Std Rate x 10,000'),
vl
.color()
.fieldN('smoke_ban')
.scale({ fill: true, range: prePostColors })
.legend(null)
)
.width(750)
.render()
Insert cell
prePostColors = ["darkgray", "steelblue"] //, "paleturquoise", "gold"]
Insert cell
{
const colors = {
domain: [0, 1],
range: ['darkgray', 'steelblue']
};
const dots = vl
.markCircle({ filled: true, size: 100 })
.data(sicily)
.encode(
vl
.x() //{ timeUnit: 'month-year' }
.fieldT('date')
.timeUnit('yearmonth')
.axis({ grid: false, format: '%b-%y' }) //tickCount: 4
.title('Year'),
vl
.y()
.fieldQ("rate")
.scale({ domain: [150, 300] })
.axis({ grid: false })
.title("Rate"),
// vl.size().count(),
vl
.color()
.fieldN("smoke_ban")
.scale(colors)
//.legend(null),
//vl.opacity().value(0.5)
);

const leastSquares = vl.markLine().encode(
vl
.x()
.fieldQ('x')
.axis(null)
.title(null),
vl
.y()
.fieldQ('y')
.title(null)
);

const colorZip = colors['domain'].map((d, i) => [d, colors['range'][i]]);

// return colorZip.map(
// ([domain, range]) => sicily.filter(d => d.smoke_ban === domain)
// // leastSquares.data(
// // leastSquaresData(
// // sicily.filter(d => d.smoke_ban === domain),
// // 'time',
// // 'rate'
// // )[0]
// // )
// );
return vl
.layer(
dots,
colorZip.map(([domain, range]) =>
leastSquares
.data(
leastSquaresData(
sicily.filter(d => d.smoke_ban === domain),
domain,
'time',
'rate'
)[0]
)
.markLine({ color: range })
),
leastSquares
.data(leastSquaresData(sicily, 0 || 1, 'time', 'rate')[0])
.markLine({ color: 'black', strokeDash: [5, 4] })
)
.width(750)
.render();
}
Insert cell
Insert cell
table(sicily)
Insert cell
printTable(sicily.slice(0, 10)) // first ten rows
Insert cell
sicily = raw.map(d => ({
...d,
rate: parseFloat(((d.aces / d.stdpop) * 10 ** 5).toFixed(3)),
date: new Date(d.year, d.month),
smoke_ban: d.smokban
}))
Insert cell
raw = FileAttachment('sicily.csv').csv({ typed: true })
Insert cell
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
import { printTable } from '@uwdata/data-utilities'
Insert cell
import { table } from '@tmcw/tables/2'
Insert cell
d3 = require('d3@6')
Insert cell
Insert cell
function leastSquaresData(data, cond, x, y) {
const [slope, intercept, rSquare] = leastSquares(
data.filter(d => d.smoke_ban === cond).map(d => d[x]),
data.map(d => d[y])
);
// return the original arguments with data for plotting a min and max (via extent) for x/y value pairs
return [
d3
.extent(data.filter(d => d.smoke_ban === cond), d => d.time)
.map(x => ({
x,
y: slope * x + intercept
})),
slope,
intercept,
rSquare
];
}
Insert cell
// returns slope, intercept and r-square of the line
// from: http://bl.ocks.org/benvandyke/8459843
function leastSquares(xSeries, ySeries) {
var reduceSumFunc = function(prev, cur) {
return prev + cur;
};

var xBar = (xSeries.reduce(reduceSumFunc) * 1.0) / xSeries.length;
var yBar = (ySeries.reduce(reduceSumFunc) * 1.0) / ySeries.length;

var ssXX = xSeries
.map(function(d) {
return Math.pow(d - xBar, 2);
})
.reduce(reduceSumFunc);

var ssYY = ySeries
.map(function(d) {
return Math.pow(d - yBar, 2);
})
.reduce(reduceSumFunc);

var ssXY = xSeries
.map(function(d, i) {
return (d - xBar) * (ySeries[i] - yBar);
})
.reduce(reduceSumFunc);

var slope = ssXY / ssXX;
var intercept = yBar - xBar * slope;
var rSquare = Math.pow(ssXY, 2) / (ssXX * ssYY);

return [slope, intercept, rSquare];
}
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