Public
Edited
May 1, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
equalBin1[0]
Insert cell
binData_parsed = equalBin1.map(arr=> {
const data = d3.mean(arr, t=> t.mean_male);
const LME = d3.mean(arr, t=> t.lm_aioe)
const IGE = d3.mean(arr, t=>t.ig_aioe)
return {'Pct. male employment': data, 'LME': LME, 'IGE': IGE}
})
Insert cell
binData_parsed_white = equalBin2.map(arr=> {
const data = d3.mean(arr, t=> t.mean_white);
const LME = d3.mean(arr, t=> t.lm_aioe)
const IGE = d3.mean(arr, t=>t.ig_aioe)
return {'Pct white employment': data, 'LME': LME, 'IGE': IGE}
})
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
bls_data = sheet_data_fn('https://docs.google.com/spreadsheets/d/e/2PACX-1vQwbQjrDn6_mgz_rtKygB7UXoekr9_iq-GQ0k1kn1gx1msCl48HXnzx_Tg0exo0WiNFc8-xEbH5cUAY/pub?gid=2015575552&single=true&output=tsv')
Insert cell
sheet_data = sheet_data_fn('https://docs.google.com/spreadsheets/d/e/2PACX-1vSHGYwJZm5TsWmcgR022LEB0PjaEXKW839GLu-5tUwInomRbOJ0edKh3cW_z7syNruWG2914dcLRCpI/pub?gid=1018282222&single=true&output=tsv')
Insert cell
getObjById = new Map(bls_data.map((obj) => [obj.occ_code, obj]));
Insert cell
getObjByTitle = new Map(bls_data.map((obj) => [obj.occ_title, obj]));
Insert cell
getObjById.get('15-1132')
Insert cell
sheet_data.map(t=> {
const Obj = getObjById.get(t.occ_code)
const Obj2 = !Obj? getObjByTitle.get(t.occ_title) :null
console.log('medianSalaryObj', Obj)
return {
...t,
'annual_median': (!Obj&& !Obj2)? 0: ((!Obj)? +(Obj2.MedianSalary.replace(',', '')) : +(Obj.MedianSalary.replace(',', ''))),
'annual_mean': (!Obj&& !Obj2)? 0: ((!Obj)? +(Obj2.MeanSalary.replace(',', '')) : +(Obj.MeanSalary.replace(',', ''))),
}
})
Insert cell
sheet_data_parsed = sheet_data.map(t=>{
t['lm_aioe'] = +t.lm_aioe
t.ig_aioe = +t.ig_aioe
t.mean_male = +t.mean_male
t.mean_white = +t.mean_white
t.mean_female = + t.mean_female
t.mean_nonwhite = +t.mean_nonwhite
t.mean_black = +t.mean_black
t.mean_asian = + t.mean_asian
t.mean_hispanic = +t.mean_hispanic
t.category=+t.category
t['category_title'] = getTitleById.get(t['category'])
return t
})
Insert cell
sheet_data_parsed_sort_by_sex = sheet_data_parsed.filter(t=> t.mean_male>0).sort((a,b)=> a.mean_male-b.mean_male)
Insert cell
sheet_data_parsed_sort_by_white = sheet_data_parsed.filter(t=> t.mean_white>0).sort((a,b)=> a.mean_white-b.mean_white)
Insert cell
equalBin1= parseDataToEqualSizedBins(sheet_data_parsed_sort_by_sex, 20)
Insert cell
equalBin2 = parseDataToEqualSizedBins(sheet_data_parsed_sort_by_white, 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_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
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
Plot = addRegression(await require("@observablehq/plot@0.6"))
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