Public
Edited
Oct 19, 2021
Insert cell
Insert cell
Insert cell
Insert cell
pos1 = {
// Recent night of a full moon, Feb 7th
// Date 0-indexes months which is weird.
let dt = new Date(2020, 1, 7);
// 22:00 or 10PM
dt.setHours(22, 0, 0, 0);
// San Francisco
let observer = {
latitude: 37.77, // 37.7749° N
longitude: -122.4, // 122.4194° W
};
let pos = suncalc.getMoonPosition(dt, observer.latitude, observer.longitude)
// Sun calc puts 0 at South, so subtract 180, since I like having 0 be North
// I'm not sure why suncalc does this, but it may have to do with "flipping"
// coordinates based on whether you're looking down at a map or up at the sky.
let toDegrees = (angle) => {
return angle * (180 / Math.PI);
}
return {
time: dt,
azimuth: toDegrees(pos.azimuth) - 180,
altitude: toDegrees(pos.altitude)
}
}
Insert cell
Insert cell
Insert cell
Insert cell
import {table} from "@tmcw/tables@513"
Insert cell
Insert cell
Insert cell
md`Next up is plotting the points. Vega-lite is the simplest way to plot line charts, so here are two charts`
Insert cell
Insert cell
Insert cell
{
let bothTables = table1.map(
(x) => {return {day: "Jan 17", ...x}}
).concat(table2.map((x) => {return {day: "Jan 18", ...x}}));

return vegalite({
autosize: "fit",
width: width/2,

data: { values: bothTables },
mark: "line",

encoding: {
x: {
field: "time",
type: "temporal"
},
y: {
field: "altitude",
minimum: 0,
},
color: {
field: "day",
}
},
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vegalite({
// I tried a bunch of things but couldn't get Vega Lite's graticules to do what I wanted.
//data: { values: table1 },
"data": {
"graticule": {
"step": [15, 15]
}
},
"mark": {
"type": "geoshape"
},
// mark: "circle",
"projection": {
"type": "stereographic",
"rotate": [0, -90, 0],
// "clipAngle": 94,
// "translate": [width/2/2, 200],
// "precision": 1,
// "scale": (width*0.15),
},
// autosize: "fit",
//width: width/2,
// "encoding": {
// "longitude": {
// "field": "azimuth",
// "type": "quantitative"
// },
// "latitude": {
// "field": "altitude",
// "type": "quantitative"
// },
// "size": {"value": 1},
// "color": {"field": "digit", "type": "nominal"}
// }
})
Insert cell
Insert cell
toDegrees = (angle) => {
return angle * (180 / Math.PI);
}
Insert cell
// Mexico City: 19.4326° N, 99.1332° W
cdmx_observer = {return {
latitude: 19.4326,
longitude: -99.1332,
}}
Insert cell
getMoonPositionDegrees = (dt, observer) => {
let pos = suncalc.getMoonPosition(dt, observer.latitude, observer.longitude)
// Sun calc puts 0 at South, so subtract 180, since I like having 0 be North
// I'm not sure why suncalc does this, but it may have to do with "flipping"
// coordinates based on whether you're looking down at a map or up at the sky.
return {
time: dt,
azimuth: (toDegrees(pos.azimuth) - 180) + 360,
altitude: toDegrees(pos.altitude)
}
}
Insert cell
getTimeStamps = (start, intervalMinutes, count) => {
let stamps = [];
let latest = start;
for (let i = 0; i < count; i += 1) {
let newTime = new Date(latest.getTime());
stamps.push(newTime);
latest.setMinutes(latest.getMinutes() + intervalMinutes);
}
return stamps;
}
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