Skip to content

Commit

Permalink
iterate on visualizations, clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
mikabr committed Oct 18, 2024
1 parent 18c10af commit 23d8ce5
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 188 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,5 @@ rsconnect/
_site/
*_files/
*_cache/

data/
41 changes: 0 additions & 41 deletions _hist.qmd

This file was deleted.

52 changes: 0 additions & 52 deletions _load-data.qmd

This file was deleted.

32 changes: 0 additions & 32 deletions _scatter.qmd

This file was deleted.

59 changes: 0 additions & 59 deletions _scatter_hist.qmd

This file was deleted.

1 change: 1 addition & 0 deletions countries-110m.json

Large diffs are not rendered by default.

143 changes: 139 additions & 4 deletions index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,146 @@ description: |
The purpose of this dataset is to offer an estimate of the horizontal momentum fluxed vertically by the atmospheric internal gravity waves (GWs) observed by Project Loon balloons. This vertical flux of horizontal momentum is commonly referred to as the GW momentum flux. Before estimating the GW momentum fluxes, additional processing was necessary to remove data sampling errors, irregularities, and balloon maneuvering.
---

<!-- {{< include _load-data.qmd >}} -->
```{r}
data <- readr::read_rds("data/loon_subset.rds") |>
dplyr::arrange(segment_id, time)
ojs_define(data = data)
```

<!-- {{< include _scatter_hist.qmd >}} -->
```{ojs}
import {interval} from '@mootari/range-slider' // two ended slider
```

<!-- {{< include _scatter.qmd >}} -->
```{ojs}
d = transpose(data).map(d => ({ ...d, time: new Date(d.time) }))
td = d.filter(d => d.segment_id == segment)
<!-- {{< include _hist.qmd >}} -->
// find minimal radius circle that includes entire flight path
minLon = d3.min(td.map(d => d.longitude))
maxLon = d3.max(td.map(d => d.longitude))
minLat = d3.min(td.map(d => d.latitude))
maxLat = d3.max(td.map(d => d.latitude))
center = [(minLon + maxLon) / 2, (minLat + maxLat) / 2]
corners = [[minLon, minLat], [minLon, maxLat], [maxLon, minLat], [maxLon, maxLat]]
dist = d3.max(corners, corner => d3.geoDistance(center, corner))
radius = dist * (180 / Math.PI)
circle = d3.geoCircle().center(center).radius(radius)()
//cor = ({"longitude": [minLon, minLon, maxLon, maxLon, center[0]],
// "latitude": [minLat, maxLat, minLat, maxLat, center[1]]})
//transpose(cor)
```

```{ojs}
//| panel: input
viewof segment = Inputs.select(Array.from(new Set(d.map(d => d.segment_id))),
{label: "Segment ID"})
viewof projection = Inputs.select(["azimuthal-equidistant", "equal-earth"],
{label: "Projection"})
```

```{ojs}
world = FileAttachment("countries-110m.json").json()
land = topojson.feature(world, world.objects.land)
viewof map_zoom = Plot.plot({
style: { fontFamily: "var(--sans-serif)" },
projection: { type: projection, domain: circle },
marks: [
Plot.frame(),
Plot.graticule(),
Plot.geo(land, {fill: "lightgrey"}),
// Plot.dot(transpose(cor), {
// x: "longitude", y: "latitude",
// r: 3, stroke: "blue", //strokeOpacity: 0.2,
// }),
Plot.dot(td.slice(1), {
x: "longitude", y: "latitude",
r: 1, stroke: "black", strokeOpacity: 0.2,
}),
Plot.dot(td.slice(0, 1), {
x: "longitude", y: "latitude",
r: 6, stroke: "red", strokeOpacity: 1, symbol: "plus"
}),
Plot.dot(td.slice(td.length - 1, td.length), {
x: "longitude", y: "latitude",
r: 6, stroke: "red", strokeOpacity: 1, symbol: "times"
})
],
})
viewof map_world = Plot.plot({
style: { fontFamily: "var(--sans-serif)" },
projection: { type: projection },
marks: [
//Plot.frame(),
Plot.sphere(),
Plot.graticule(),
Plot.geo(land, {fill: "lightgrey"}),
Plot.dot(td.slice(1), {
x: "longitude", y: "latitude",
r: 1, stroke: "black", strokeOpacity: 0.2,
}),
Plot.dot(td.slice(0, 1), {
x: "longitude", y: "latitude",
r: 3, stroke: "red", strokeOpacity: 1, symbol: "plus"
}),
Plot.dot(td.slice(td.length - 1, td.length), {
x: "longitude", y: "latitude",
r: 3, stroke: "red", strokeOpacity: 1, symbol: "times"
})
],
})
html`<div style="display: flex;">
<div style="flex-basis:50%"> ${viewof map_zoom} </div>
<div style="flex-basis:50%"> ${viewof map_world} </div>
</div>`
```

```{ojs}
viewof scatter_alt = Plot.plot({
style: { fontFamily: "var(--sans-serif)" },
width: 900,
height: 200,
inset: 8,
grid: true,
y: { label: "Altitude (meters)" },
marks: [
Plot.dot(td, { x: "time", y: "altitude", r: 0.5 }),
]
})
winds = new Map([["Zonal (east-west)", "wind_u"],
["Meridional (north-south)", "wind_v"]])
viewof y_wind = Inputs.select(winds, {label: "Wind direction"})
viewof scatter_wind = Plot.plot({
style: { fontFamily: "var(--sans-serif)" },
width: 900,
height: 200,
inset: 8,
grid: true,
y: { label: "Velocity (meters/second)" },
marks: [
Plot.dot(td, { x: "time", y: y_wind, r: 0.5 }),
]
})
fluxes = new Map([["East", "flux_east"], ["West", "flux_west"],
["North", "flux_north"], ["South", "flux_south"]])
viewof y_flux = Inputs.select(fluxes, {label: "Flux direction"})
viewof scatter_flux = Plot.plot({
style: { fontFamily: "var(--sans-serif)" },
width: 900,
height: 200,
inset: 8,
grid: true,
y: { label: "Flux (pascals)", transform: (f) => f * 1000 },
marks: [
Plot.dot(td, { x: "time", y: y_flux, r: 0.5 }),
]
})
```

0 comments on commit 23d8ce5

Please sign in to comment.