Public
Edited
Jan 11, 2024
2 forks
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { getMeasurementData, luts } from "@maris-iaea/api"
Insert cell
Insert cell
params = ({
sampleTypeId: 1,
nuclideId: 33,
samplingDateFrom: "2009-01-01",
samplingDateTo: "2024-01-01"
})
Insert cell
Insert cell
luts.nuclides
Insert cell
luts.sampleTypes
Insert cell
Insert cell
dataRaw = getMeasurementData(params)
Insert cell
Insert cell
Insert cell
Object.keys(dataRaw[0])
Insert cell
Insert cell
Insert cell
dataSelected = dataRaw.map(d => ({lat: d.latitude,
lon: d.longitude,
time: new Date(d.begPeriod),
depth: d.sampleDepth,
isDetected: d.detection,
activity: d.activity,
unit: d.unit
}))
Insert cell
Insert cell
dataSelected.map(d=> ({...d,
activity: d.unit === 'Bq/m3' ? d.activity: d.activity/(1.025*1000),
unit: 'Bq/m3'}))
Insert cell
Insert cell
data = dataSelected.filter(d=> d.isDetected === '=')
Insert cell
data
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
Plot.plot({
x: {
round: true,
ticks: 10,
transform: (d) => Math.pow(10, d),
type: "log",
tickFormat: "~s",
label: `Activity in Bq/m3 (log scale) →`
},
y: {
label: "Count ↑"
},
marks: [
Plot.rectY(
data,
Plot.binX(
{ y: "count" },
{
x: (d) => Math.log10(d.activity || NaN),
inset: 0
}
)
)
],
height: 200
})
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.rectY(
data,
Plot.binX({ y: "count" }, { x: "time", tip: true })
),
Plot.ruleY([0])
],
height: 200
})
Insert cell
Insert cell
Insert cell
hexTimeChart = Plot.plot({
color: { scheme: "OrRd" },
y: {
type: "log",
tickFormat: "~s",
inset: 6
},
marks: [
Plot.dot(
data,
Plot.hexbin(
{ fill: "count" },
{
x: "time",
y: "activity",
symbol: "hexagon",
fillOpacity: 0.9,
stroke: "black",
strokeWidth: 0.5,
strokeOpacity: 0.5,
binWidth: 7,
tip: true
}
)
)
]
})
Insert cell
Insert cell
Insert cell
Plot.plot({
width: 450,
// height: 450,
projection: {
type: "equal-earth",
},
marks: [
Plot.dot(data, {
x: "lon",
y: "lat",
// uncomment the line below to see how radius can reflect activity levels
// r: d=> Math.log(d.activity),
fill: "black",
fillOpacity: 0.5,
stroke: 'white'
})
]
})
Insert cell
Insert cell
Insert cell
world = (
await fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/land-50m.json")
).json()
Insert cell
Insert cell
land = topojson.feature(world, world.objects.land)
Insert cell
Insert cell
Insert cell
Plot.plot({
projection: {
type: "equal-earth",
},
marks: [
Plot.geo(land, {
fill: "#ffffff",
stroke: "black",
strokeWidth: 0.5
}),
Plot.graticule(),
Plot.dot(data, {
x: "lon",
y: "lat",
// uncomment the line below to see how radius can reflect activity levels
// r: d=> Math.log(d.activity),
fill: "black",
fillOpacity: 0.5,
stroke: 'white'
}),
Plot.sphere({ strokeWidth: 0.5 })
],
// width: 1100
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// feel free to adjust it
activityBins = [1, 20, 1000, 10000]
Insert cell
Insert cell
Insert cell
activityWorld = Plot.plot({
color: {
type: "threshold",
scheme: "YlGnBu",
domain: activityBins
},
projection: {
type: "equal-earth"
},
marks: [
Plot.geo(land, {
fill: "#ffffff",
stroke: "black",
strokeWidth: 0.5
}),
Plot.graticule(),
Plot.dot(
data,
Plot.hexbin(
{
// replace max by mean, median, ...
fill: (g) => d3.max(g, (d) => d.activity),
},
{
x: "lon",
y: "lat",
fillOpacity: 0.9,
symbol: "hexagon",
stroke: "black",
strokeWidth: 0.2,
binWidth: 8,
}
)
),
Plot.sphere({ strokeWidth: 0.5 })
]
})
Insert cell
Insert cell
viewof depth = Inputs.range([-1, 100], {
value: 0,
step: 1,
label: "Max depth (m) of interest: "
})
Insert cell
Insert cell
activityWorldDepth = Plot.plot({
color: {
type: "threshold",
scheme: "YlGnBu",
domain: activityBins
},
projection: {
type: "equal-earth",
// To change center ...
rotate: [-125, 0],
},
marks: [
Plot.geo(land, {
fill: "#ffffff",
stroke: "black",
strokeWidth: 0.5
}),
Plot.graticule(),
Plot.dot(
data,
Plot.hexbin(
{
fill: (g) => d3["max"](g, (d) => d.activity),
},
{
x: "lon",
y: "lat",
fillOpacity: 0.9,
symbol: "hexagon",
stroke: "black",
strokeWidth: 0.2,
binWidth: 8,
filter: (d => d.depth <= depth),
}
)
),
Plot.sphere({ strokeWidth: 0.5 })
]
})
Insert cell
Insert cell
Insert cell
center = [141.042132, 37.423152] // lon, lat of FDNPP
Insert cell
viewof kms = Inputs.range([0, 3000], {
value: 300,
step: 10,
label: "Radius around selected center point(in km): "
})
Insert cell
Insert cell
circle = d3
.geoCircle()
.center(center)
.radius((kms / (6371 * Math.PI * 2)) * 360)
.precision(10)()
Insert cell
Insert cell
dataWithinRadius = data.filter(
(d) => d3.geoDistance([d.lon, d.lat], center) < kms / 6371
)
Insert cell
Insert cell
activityFDNPP = Plot.plot({
color: {
type: "threshold",
scheme: "YlGnBu",
domain: activityBins
},
projection: {
type: "azimuthal-equidistant",
rotate: center.map((d) => -d),
domain: circle,
inset: 20
},
marks: [
Plot.geo(land, {
fill: "#ffffff",
stroke: "black",
strokeWidth: 0.5
}),
Plot.graticule(),
Plot.dot(
dataWithinRadius,
Plot.hexbin(
{
fill: (g) => d3["max"](g, (d) => d.activity),
},
{
x: "lon",
y: "lat",
fillOpacity: 0.9,
symbol: "hexagon",
stroke: "black",
strokeWidth: 0.2,
binWidth: 8,
}
)
),
Plot.geo(circle, {
stroke: "#bbb",
strokeWidth: 1,
strokeDasharray: "5,3"
}),
Plot.sphere({ strokeWidth: 0.5 })
],
width: 500
})
Insert cell
Let's define our time period of interest:
Insert cell
timePeriod = [2006, 2011, 2012, 2015, 2017, 2020, 2023]
Insert cell
Insert cell
Insert cell
activityFDNPPTime = Plot.plot({
color: {
type: "threshold",
scheme: "YlGnBu",
domain: activityBins
},
projection: {
type: "azimuthal-equidistant",
rotate: center.map((d) => -d),
domain: circle,
},
fx: {
transform: (d) => timeScale(d.getFullYear()),
label: "Date →",
reverse: false,
},
facet: {
data: dataWithinRadius,
x: "time",
},
marks: [
Plot.geo(land, {
fill: "#ffffff",
stroke: "black",
strokeWidth: 0.5
}),
Plot.graticule(),
Plot.dot(
dataWithinRadius,
Plot.hexbin(
{
fill: (g) => d3["max"](g, (d) => d.activity),
},
{
x: "lon",
y: "lat",
fillOpacity: 0.9,
symbol: "hexagon",
stroke: "black",
strokeWidth: 0.2,
binWidth: 5,
// facet: "include"
}
)
),
Plot.geo(circle, {
stroke: "#bbb",
strokeWidth: 1,
strokeDasharray: "5,3"
}),
Plot.sphere({ strokeWidth: 0.5 })
],
width
})
Insert cell
Insert cell
timeScale = function(array) {
const timeDomain = array.slice(1, -1)
const timeRange = d3.pairs(array).map((d) => `${d[0]} - ${d[1]}`)
return d3.scaleThreshold().domain(timeDomain).range(timeRange)
}(timePeriod)
Insert cell
Insert cell
Insert cell
import {toc} from "@mbostock/toc"
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