Public
Edited
Feb 19, 2024
Insert cell
Insert cell
db = DuckDBClient.of({
ne: FileAttachment("global_ne_3dvar.parquet")
})
Insert cell
global_ne_3dvar.parquet
SELECT time, alt, global_ne_3dvar AS ne
FROM 'global_ne_3dvar'
WHERE time BETWEEN '2023-09-08' AND '2023-09-14'
Insert cell
data
Insert cell
colorScaleOptions = ({
type: "sequential",
domain: d3.extent(data, (d) => d["ne"]),
scheme: "Inferno",
tickFormat: "~g",
nice: true,
reverse: true
})
Insert cell
Insert cell
Plot.plot({
width: 1800,
height: 1200,
marginLeft: 10,
marginTop: 0,
marginRight: 50,
x: {
interval: d3.utcHour,
ticks: d3.utcTicks(...d3.extent(data, (d) => d["time"]), 10)
},
y: {
axis: "right",
reverse: true,
tickFormat: ",d",
label: "altitude (km)"
// interval: 10
// ticks: d3.ticks(data, (d) => d["alt"], 10),
},
color: colorScaleOptions,
marks: [
Plot.rect(data, {
x: "time",
y: "alt",
fill: "ne",
inset: 0
})
]
})
Insert cell
ne@1.parquet
SELECT
time,
alt,
min(ne) AS min_ne,
median(ne) AS median_ne,
max(ne) AS max_ne
FROM 'ne'
GROUP BY time, alt
Insert cell
d3.max(altData, (d) => d.median_ne)
Insert cell
altitudeProfile = (data, reverse = false, fill = "#d1d5db") => {
const domain = [1e6, 1e12];
return Plot.plot({
width: 400,
height: 400,
y: {
axis: "right",
grid: true,
type: "log"
},
x: {
type: "log",
tickFormat: "~g",
domain,
reverse
},
marks: [
Plot.areaX(data, {
x1: 1e6,
x2: "median_ne",
y: "alt",
fill,
fillOpacity: 0.5
}),
Plot.ruleY([altData[d3.maxIndex(data, (d) => d.median_ne)]], {
y: "alt",
x1: domain[0],
x2: d3.max(data, (d) => d.median_ne)
})
]
});
}
Insert cell
altitudeProfile(
altData.filter((d) => d.time.getDate() == 11),
true,
"#1e40af"
)
Insert cell
altitudeProfile(
altData.filter((d) => d.time.getDate() == 14),
false,
"#b91c1c"
)
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