Public
Edited
Jan 23
4 forks
19 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
label = (i) => (labels[i] ? ` (${labels[i]})` : "") // for title tooltip
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
color = ({
domain: d3.range(n * n),
range: d3.cross(blues, oranges).map(mixblend)
})
Insert cell
function mixblend([a, b]) {
a = d3.rgb(a);
b = d3.rgb(b);
const l = Math.min(250, b.r + b.g + b.b);
a.r *= b.r / l;
a.g *= b.g / l;
a.b *= b.b / l;
return a.hex();
}
Insert cell
quantilesPrecipitation = d3
.scaleQuantile()
.domain(mainMapClimateData.ppt) // Use the precipitation data
.range(d3.range(n)) // Map the data to quantiles
.quantiles() // Get the quantiles
Insert cell
quantilesTemperature = d3
.scaleQuantile()
.domain(mainMapClimateData.temp) // Use the precipitation data
.range(d3.range(n)) // Map the data to quantiles
.quantiles() // Get the quantiles
Insert cell
function interpolateBivariate(n, v1, v2) {
const r = d3.range(n);
const s1 = d3.scaleQuantile(v1, r);
const s2 = d3.scaleQuantile(v2, r);
const interpolate = Plot.interpolatorBarycentric();
return function (I, w, h, X, Y) {
I = I.filter((i) => !isNaN(v1[i]) && !isNaN(v2[i]));
const V1 = interpolate(I, w, h, X, Y, v1);
const V2 = interpolate(I, w, h, X, Y, v2);
return Uint8Array.from(V1, (_, i) => n * s1(V1[i]) + s2(V2[i]));
};
}

Insert cell
Insert cell
countries = await FileAttachment("countries-10m.json")
.json()
.then((world) =>
topojson.feature(world, {
type: "GeometryCollection",
// Maldives has a wrong winding order.
geometries: world.objects.countries.geometries.filter(
({ properties: { name } }) => name !== "Maldives"
)
})
)
Insert cell
land = FileAttachment("CNTR_RG_10M_2024_4326.json")
.json()
.then((world) =>
topojson.feature(world, {
type: "GeometryCollection",
// Maldives has a wrong winding order.
geometries: world.objects.CNTR_RG_10M_2024_4326.geometries.filter(
({ properties: { name } }) => name !== "Maldives"
)
})
)
Insert cell
states = FileAttachment("us-states.json").json()
Insert cell
Insert cell
mainMapClimateData = {
let _ppt = await locationConfigs[location].data.ppt.arrayBuffer().then(cdf);
let _tmax = await locationConfigs[location].data.tmax.arrayBuffer().then(cdf);
let _tmin = await locationConfigs[location].data.tmin.arrayBuffer().then(cdf);

let tmax = await Float32Array.from(_tmax.getDataVariable("tmax"), (d) =>
d !== -32768 ? d * 0.01 - 99 : NaN
);
let tmin = await Float32Array.from(_tmin.getDataVariable("tmin"), (d) =>
d !== -32768 ? d * 0.01 - 99 : NaN
);
let ppt = Float32Array.from(_ppt.getDataVariable("ppt"), (d) =>
d !== -2147483648 ? d * 0.1 : NaN
).map((d) => (d < 10 ? NaN : d));
let lx = _tmax.getDataVariable("lon");
let ly = _tmax.getDataVariable("lat");
let l = lx.length;
let temp = tmax.map((max, i) => (max + tmin[i]) / 2);
let lon = (d, i) => lx[i % l];
let lat = (d, i) => ly[(i / l) | 0];

return {
ppt,
tmax,
tmin,
tmax,
tmin,
ppt,
lx,
ly,
l,
temp,
lon,
lat
};
}
Insert cell
Insert cell
insetMapClimateData = {
if (locationConfigs[location].data.inset) {
let _ppt = await locationConfigs[location].data.inset.ppt
.arrayBuffer()
.then(cdf);
let _tmax = await locationConfigs[location].data.inset.tmax
.arrayBuffer()
.then(cdf);
let _tmin = await locationConfigs[location].data.inset.tmin
.arrayBuffer()
.then(cdf);
let tmax = Float32Array.from(_tmax.getDataVariable("tmax"), (d) =>
d !== -32768 ? d * 0.01 - 99 : NaN
);
let tmin = Float32Array.from(_tmin.getDataVariable("tmin"), (d) =>
d !== -32768 ? d * 0.01 - 99 : NaN
);
let ppt = Float32Array.from(_ppt.getDataVariable("ppt"), (d) =>
d !== -2147483648 ? d * 0.1 : NaN
).map((d) => (d < 10 ? NaN : d));
let lx = _tmax.getDataVariable("lon");
let ly = _tmax.getDataVariable("lat");
let l = lx.length;
let temp = tmax.map((max, i) => (max + tmin[i]) / 2);
let lon = (d, i) => lx[i % l];
let lat = (d, i) => ly[(i / l) | 0];
return {
ppt,
tmax,
tmin,
tmax,
tmin,
ppt,
lx,
ly,
l,
temp,
lon,
lat
};
}

return;
}
Insert cell
Insert cell
Insert cell
requests = {
const vars = ["ppt", "tmax", "tmin"];
const URLS = [];
//UK
// const LAT_MIN = 49.674;
// const LON_MIN = -14.015517;
// const LAT_MAX = 61.061;
// const LON_MAX = 2.0919117;

// Europe
const LAT_MIN = 32;
const LON_MIN = -24.2;
const LAT_MAX = 71.2;
const LON_MAX = 62;

//South america
// const LAT_MIN = -55; // Southern tip
// const LON_MIN = -81.3; // Western tip
// const LAT_MAX = 13; // Northern tip
// const LON_MAX = -34.8; // Eastern tip

//continental US
// const LAT_MIN = 24.396308; // Southern tip
// const LON_MIN = -125; // Western tip
// const LAT_MAX = 49.384358; // Northern tip
// const LON_MAX = -66.93457; // Eastern tip

// Iberian peninsula
// const LAT_MIN = 35.9; // Southernmost point
// const LON_MIN = -9.5; // Westernmost point
// const LAT_MAX = 43.8; // Northernmost point
// const LON_MAX = 4.3; // Easternmost point

//canaries
// const LAT_MIN = 27.6; // Southernmost point of the Canary Islands
// const LON_MIN = -18.2; // Westernmost point of the Canary Islands
// const LAT_MAX = 29.5; // Northernmost point of the Canary Islands
// const LON_MAX = -13.3; // Easternmost point of the Canary Islands

vars.forEach((param) => {
URLS.push(
`http://thredds.northwestknowledge.net:8080/thredds/ncss/agg_terraclimate_${param}_1958_CurrentYear_GLOBE.nc?var=${param}&south=${LAT_MIN}&north=${LAT_MAX}&west=${LON_MIN}&east=${LON_MAX}&disableProjSubset=on&addLatLon=true&horizStride=1&accept=netcdf`
);
});

return URLS;
}
Insert cell
//ppt_raw = await fetch(requests[0])
Insert cell
Insert cell
function cdf(buffer) {
return new netcdfjs.NetCDFReader(buffer);
}
Insert cell
netcdfjs = import("https://cdn.skypack.dev/netcdfjs@3.0.0?min")
Insert cell
Plot = require(await FileAttachment("plot.umd.js").url()) // https://github.com/observablehq/plot/pull/2243
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