Public
Edited
May 4, 2023
1 fork
Insert cell
Insert cell
Insert cell
viewof minFreq = Inputs.range([-2.5, 1.5], {label: "AI occupation exposure", step: .1, value: 0})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
facet: {
data: sheet_data_parsed,
y: "category_title",
marginLeft: 250
},
marks: [
Plot.frame({stroke: "#aaa", strokeWidth: 0.5}),
Plot.dot(sheet_data_parsed, {x: "LME", y: "MedianSalary", r: 2, fill:'steelblue'}),
Plot.dot(sheet_data_parsed, {x: "IGE", y: "MedianSalary", r: 2, fill:'darkorange'}),
Plot.ruleX(
sheet_data_parsed, // object must === the facet data
Plot.groupZ(
{ x: "median" }, // the reducer you want to apply
{ x: "LME", stroke: 'steelblue', strokeDasharray: [3, 2] } // the dimension you want to apply the reducer to
)
),
Plot.ruleX(
sheet_data_parsed, // object must === the facet data
Plot.groupZ(
{ x: "median" }, // the reducer you want to apply
{ x: "IGE", stroke: 'darkorange', strokeDasharray: [3, 2] } // the dimension you want to apply the reducer to
)
),
Plot.ruleX(
sheet_data_parsed, // object must === the facet data
{ x: 0 }
),
// Plot.ruleX([d3.mean(sheet_data_parsed, d=>d.LME)] , {stroke: "orange"}),
// Plot.line(
// sheet_data_parsed,
// Plot.regression({
// x: "LME",
// y: "MedianSalary",
// strokeDasharray: [1.5, 4],
// strokeWidth: 1.5,
// stroke: 'steelblue',
// })
// ),
// Plot.line(
// sheet_data_parsed,
// Plot.regression({
// x: "IGE",
// y: "MedianSalary",
// strokeDasharray: [1.5, 4],
// strokeWidth: 1.5,
// stroke: 'darkorange',
// })
// ),
],
width: 1000,
height: 2000,
marginTop: 0,
marginLeft: 200,
x: {inset: 10, grid: true, label: "AI Exposure →"},
y: {axis: null, inset: 2},
color: {legend: true},
style: {fontSize: "12px"},
})
Insert cell
Insert cell
LME_ranking = d3.rollups(sheet_data_parsed, v => d3.median(v, d => d.LME), d => d.category)
Insert cell
LME_ranked = LME_ranking.sort( (a, b)=> a[1]-b[1]).map(t=> ({'category': t[0],'category_title': getTitleById.get(t[0]), 'LME_median': t[1]}))
Insert cell
IGE_ranked=IGE_ranking.sort( (a, b)=> a[1]-b[1]).map(t=> ({'category': t[0],'category_title': getTitleById.get(t[0]), 'IGE_median': t[1]}))
Insert cell
IGE_ranking = d3.rollups(sheet_data_parsed, v => d3.median(v, d => d.IGE), d => d.category)
Insert cell
Insert cell
binning = d3.bin()
.value(d => d.MedianSalary) // Use the "age" attribute as the value
.thresholds(salary_range); // Define the bin boundaries
Insert cell
Insert cell
// Group the data into bins
sheetData_bins = binning(sheet_data_parsed);
Insert cell
bin1 = d3.bin()
Insert cell
occupation_by_salary_aioe[0]
Insert cell
Plot.plot({
marks: [
Plot.rectY(occupation_by_salary_aioe, Plot.binX({y: "count"}, {x: "median_salary_2021", fill:'AIOE' })),
Plot.ruleY([0])
],
color: {
legend: true
},
x: {
domain: [0, 200]
}
})
Insert cell
Insert cell
data = FileAttachment("penguins.csv").csv({typed: true})
Insert cell
height = 400
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(data, d => d.flipper_length_mm)).nice()
.range([margin.left, width - margin.right])
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(data, d => d.body_mass_g)).nice()
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
Insert cell
margin = ({top: 25, right: 20, bottom: 35, left: 40})
Insert cell
occupation_by_salary_aioe.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
occupation_by_salary_aioe
Insert cell
sheet_data = sheet_data_fn('https://docs.google.com/spreadsheets/d/e/2PACX-1vSHGYwJZm5TsWmcgR022LEB0PjaEXKW839GLu-5tUwInomRbOJ0edKh3cW_z7syNruWG2914dcLRCpI/pub?gid=235058841&single=true&output=tsv')
Insert cell
sheet_data_parsed = sheet_data.map(t=>{
t['LME'] = +t['LME']
t['IGE'] = +t['IGE']
t['MeanSalary'] = +t['MeanSalary']
t['MedianSalary'] = +t['MedianSalary']
t['category'] = + t.category
t['category_title'] = getTitleById.get(t['category'])
return t
})
Insert cell
sheet_data_parsed_sort_by_salary = sheet_data_parsed.filter(t=> t.MedianSalary>0).sort((a,b)=> a.MedianSalary-b.MedianSalary)
Insert cell
equalBin1= parseDataToEqualSizedBins(sheet_data_parsed_sort_by_salary, 20)
Insert cell
function parseDataToEqualSizedBins(sortedData, numBins){

// Calculate the size of each bin
const binSize = Math.ceil(sortedData.length / numBins);

// Create the equal-sized bins
const equalSizedBins = [];

for (let i = 0; i < sortedData.length; i += binSize) {
equalSizedBins.push(sortedData.slice(i, i + binSize));
}
return equalSizedBins
}
Insert cell
getTitleById = new Map(occ_title.map((obj) => [+obj.code, obj['Occupation Title']]));

Insert cell
occ_group_parsed = sheet_data_fn('https://docs.google.com/spreadsheets/d/e/2PACX-1vSHGYwJZm5TsWmcgR022LEB0PjaEXKW839GLu-5tUwInomRbOJ0edKh3cW_z7syNruWG2914dcLRCpI/pub?gid=2022877740&single=true&output=tsv')
Insert cell
occ_title = sheet_data_fn('https://docs.google.com/spreadsheets/d/e/2PACX-1vSHGYwJZm5TsWmcgR022LEB0PjaEXKW839GLu-5tUwInomRbOJ0edKh3cW_z7syNruWG2914dcLRCpI/pub?gid=1337766510&single=true&output=tsv')
Insert cell
async function sheet_data_fn (new_url){
let sheet_data =[];
const spreadsheet = await d3.tsv(new_url)
.then(data => data.forEach(d => {
// d[''] = months[+ d.DATE.split("/")[0] -1 ]
sheet_data.push(d);
} )); // d3.tsv returns a Promise

return sheet_data;
}
Insert cell
Insert cell
function entity(character) {
return `&#${character.charCodeAt(0).toString()};`;
}
Insert cell
Plot = addRegression(await require("@observablehq/plot@0.6"))
Insert cell
function addRegression(Plot) {
Plot.regression = function ({ x, y, type, bandwidth, order, ...options }) {
type = String(type).toLowerCase();
const regressor =
type === "quad"
? reg.regressionQuad()
: type === "poly"
? reg.regressionPoly()
: type === "pow"
? reg.regressionPow()
: type === "exp"
? reg.regressionExp()
: type === "log"
? reg.regressionLog()
: type === "loess"
? reg.regressionLoess()
: reg.regressionLinear();
if (bandwidth && regressor.bandwidth) regressor.bandwidth(bandwidth);
if (order && regressor.order) regressor.order(order);

const z = options.z || options.stroke; // maybeZ
return Plot.transform(options, function (data, facets) {
const X = Plot.valueof(data, x);
const Y = Plot.valueof(data, y);
const Z = Plot.valueof(data, z);
regressor.x((i) => X[i]).y((i) => Y[i]);

const regFacets = [];
const points = [];
for (const facet of facets) {
const regFacet = [];
for (const I of Z ? d3.group(facet, (i) => Z[i]).values() : [facet]) {
const reg = regressor(I);
for (const d of reg) {
const j = points.push(d) - 1;
if (z) d[z] = Z[I[0]];
regFacet.push(j);
}
}
regFacets.push(regFacet);
}
return { data: points, facets: regFacets };
});
};
return Plot;
}
Insert cell
reg = require("d3-regression@1")
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