happy equinox

06:38 21/03/2024 2633 words
13:07 31/05/2024 (modified)
contents

the rate of change of daylight is presently at its greatest.

a few days ago[1], izgi and i were too early for sunrise.

yesterday[2] we witnessed it.

and this morning[3] we missed it.

i know, i know, one should always carpe the diem[4]. but now is really the time to start putting the evenings and mornings to good use.

an example of a thing that does not qualify as a good use of daylight would be writing some code to visualize how much daylight you 're wasting have[5]. that's why i mostly wrote the code for this project over the course of several winters (granted, there were probably some wasted bluebird days).


the goal

a calendar that lets you know where the sun is relative to a specified location.[6]

v.1.

the first version was done in matlab at the tail end of 2020. it looked pants. and i can't find a copy of it. last seen on a since deleted student onedrive account.

the detail i wanted to communicate - because it's the thing i find most captivating about the sun's path - is where does the sun rise and set on any given day, and how does that change over the course of a year.

the approach taken was to show each day as a circular mini-map with the specified location at the centre. within each circle, was a sector bound by two radii that point towards where the sun rises and sets. the lengths of these radii scaled with the solar elevation at noon on that day. each circle was coloured according to the number of daylight hours; and the time of sunrise / sunset were placed along each of the sector radii.

this design worked. and i was certainly pleased with it at the time. but...the code was inefficient (if my memory can be trusted: each day's sector was plotted on its own single polar axes instance; and it was very loopy and not very vectorizedy). and it wasn't that much of a looker.

v.2.

skip forward a year, and i'd moved away from matlab and into python and the joys of matplotlib. i replicated the original design, and greatly improved the plotting performance by using patches and converting each polar plot into cartesian coordinates that were then offset by day of month and month of year. ta-dah. only a single axis required. this looked like this:

an ugly calendar
Fig -1: an ugly calendar

i am still quite happy with it. there are additional details such as the font colour changing from white to black and back on the equinoxes. dotted lines around solstices. and the month names and day numbers actually line up with the centre of the circles. which was very much not the case on v.1.

the following year (2022-23) i went a bit abstract:

abstract calednar with each represented as a series of loops, each month is on its own row. winter months are in blues, summer months in reds and oranges
Fig 0: apples

during the winter that's just finished, i started again. from the ground up.

v.3.

rethink

heavily drawing inspiration from sharon lee's tide charts, i wanted something that connected the days together: a way of representing the earth's continuous rotation and orbit, via the sun's (apparent) continuous motion. by using the horizontal coordinate system, the sun's position for an observer at a given location and time can be represented by two angular quantities:


step 1: altitude

altitude lends itself nicely to plotting, as it can be described by a sine wave[7], the amplitude of which is a function of latitude. every day, the sun crosses the horizon (sunrise), rises to a maximum at solar noon[8], crosses the horizon again (sunset), and then descends to a minimum at the opposite of solar noon.

in summer, the sun spends more time above the horizon. the days are longer. in winter, it spends more time below the horizon (fig 1).

graphing showing solar elevation against day of month for june in blue, and and december in green
Fig 1: solar elevation (degrees) over the course of june (blue) and december (green) as seen from Finse, Norway (60.59 °n, 7.52 °e). an elevation of 0° corresponds to the horizon.

notice how the daily amplitude doesn't change much from month-to-month; instead, the whole wave shifts up and down with the seasons. this allows for plotting each month on its own row, with a consistent scale, but different limits. like so (fig 2).

two graphs showing solar elevation against days of month for June and December. both axes are to the same scale, showing the amplitude of variation is the same in both months, however in december the whole plot is shifted down
Fig 2: olar elevation (degrees) over the course of june (blue, top) and december (green, bottom) as seen from Finse, Norway (60.59 °n, 7.52 °e). an elevation of 0° corresponds to the horizon. **note**: different limits on each axis, which can be readily seen by the horizon shift. and plots are to the same scale, i.e., both span ~60° from top to bottom.

by plotting each month on its own row, the calendar becomes familiar, and legible (at least, i hope it does). the consistent scale, but differing limits, enables a fair and meaningful comparison to be made. differences between months can be further enhanced by emphasizing the feature that changes - i.e. the horizon - by plotting it in a high contrast colour.

this is the foundation of the calendar done.

step 2: azimuth

plotting azimuth as a time series is problematic because of the discontinuity at 0°/360°. but that's ok, because circular colour-maps[9] are a thing. and they are masterful. and i love them.

graph showing solar azimuth over the course of a week. azimuth is also coloured on a circular colour map from dark blues at 0 to whites at 180 and then dark reds and 360
Fig 3: solar azimuth for a few days in january. every day at solar midnight, the azimuth jumps down from 360° to 0° (dashed line), but **note** how the colour at the top and bottom match.

the altitude lines in fig. 2. can be coloured by azimuth, a la fig. 3. so, in addition to going up and down, the lines smoothly change colour as the sun whirls around.

by rotating the colour map, so that the brightest hues align with solar noon, it should (i hope) be reasonably easy, and intuitive, to differentiate day and night (fig. 4.) furthermore, the colour of the altitude line where it crosses the horizon enables the bearing of sunrise / sunset to be roughly ascertained[10]

two graphs showing the solar elevation over the course of four days in march, and December. the line is also coloured by solar azimuth. times and bearings of sunrise and sunset are marked.
Fig 4: solar altitude (degrees) plotted for four days in march (top) and december (bottom). path is coloured by azimuth where the path crosses the horizon (altitude = 0°) the azimuth corresponding to the colour has been annotated with vertical lines. **note**: how in march - near the equinox - there is rapid change in sunrise / sunset bearing over the course of a few days. whereas in december - near the solstice - these values are unchanging.

step 3: decorations

adding a few other features

compass rose and solar paths

instead of the using a colour bar (as in fig. 3. & 4.), much better to put wrap it around a compass rose (fig. 5.) that is, after all, the whole point of circular colour maps.

a compass rose, coloured from dark in the north, to light blue in the east, white in the south and red/orange in the west. the paths the sun traces on the summer, and winter solstices and the equinoxes are traced in the middle of the of the circle
Fig 5: compass rose / azimuth legend with cyclic colour map, and polar plot of solar paths during the summer (solid line) and winter (dashed line) solstices and the equinoxes (dash-dot line). _remember_: the sun rises in the east and sets in the west: that's right to left in this representation.

the compass rose permits the inclusion of a little bonus feature: nestled within are polar plots of the solar path. this can be imagined as a map, with the observer at the centre. the edge of the circle represents the horizon. the centre of the circle is directly overhead. here the sunrises ~ne on the summer solstice, and ~se on the winter solstice. the sun stays low in the sky (close to outside of circle) in winter, whereas it rises high (middle of circle) on the summer solstice. i should probably add arrows to show the direction...

analemma

might as well add an analemma too (fig. 6.). this shows the sun's elevation and azimuth plotted against one another, for a given clock time for every day of the year. this is very closely related (i.e. the same darn thing) as the equation of time, and it goes some way towards explaining why solar noon does not always coincide with midday. add in a few solstice and equinox annotations, and it becomes sort of informative.

an analemma
Fig 6: analemma. showing the sun's altitude (°) against its azimuth (°) at 12:00 every day for a year

daylight hours

whilst the altitude line (fig. 4.) gives a good sense of how much time per day the sun is above the horizon. it'd be nice to get a clearer idea of just how daylight duration changes over the course of the year. enter fig. 7.

sun graph, showing astronomical, nautical and cival twilight, along with dayling for a calendar year at Finse.
Fig 7: un graph. this shows periods of daylight, and all the twilights over the course of year. the lines separating each twilight band are coloured by solar azimuth. for example, in december, astronomical twilight gives way to nautical twilight in the morning when the sun is a bit east of se, whereas in june astronomical twilight just ain't a thing in Finse. note the steps when daylight saving changes are made.

annotations

on the main plot - add the sunrise and sunset times above the maximum and minimum altitude, respectively. and add a few vertical lines for the solstices, and equinoxes, and daylight saving. add labels for the vertical lines into the margins here and there. and a label telling the reader that the horizon is the horizon.

i can't be bothered to rustle up another plot illustrating just these features.

styling

here, i've been using the solarized_light2[11] theme, because i like it. for the actual calendar, i opted for dark.

font - dejavu sans mono. naturally.

frame - alternating black and white - very much borrowing from the tide charts[12].

the finished thing


Calendar of solar positions at 60.59 N 7.52E for 2024
Fig 8: the finished thing

which i am reasonably happy with.

things that i would like to improve in v4:


once the code is a bit cleaner, i'll link to it.

credits

many a python library creator, and many more astronomers leant a hand

footnotes


  1. last week? ↩︎

  2. which is now the day before yesterday, or maybe even the day before that. grand plans of publishing this at 03:07 on 20th March were thwarted by work. and perfectionist tendencies. ↩︎

  3. which wasn’t also not this morning – although, i probably missed sunrise this morning too. ↩︎

  4. yes, that is a succession reference. ↩︎

  5. or writing about how you wrote some code. ↩︎

  6. on earth’s surface ↩︎

  7. did i just needlessly verify this for myself by mucking about scipy.optimize.curve_fit? of course. ↩︎

  8. which is a bit different to 12:00. ↩︎

  9. i didn’t use one of fabio crameri’s excellent colour maps, instead i opted for matplotlib‘s twilight. but, having just had a look at fabio’s site, roma0 looks fantastic. relatedly: it was this paper by thyng et al., (2016) that first opened my eyes to the thinking behind colour maps. ↩︎

  10. a bonus feature in the final version - and perhaps my favourite bonus feature – the line appears to go behind the horizon at sunset, and it comes up above the horizon at sunrise. ↩︎

  11. if wordpress had a solarized light theme, i’d be using it ↩︎

  12. imitation is the sincerest form of flattery etc... ↩︎

  13. very ↩︎

  14. that said, i just tried a few, and it can handle it, but it looks a bit weird. the text labels for sunrise / sunset times stop abruptly. maybe putting a ‘ – ‘ in place of nothing. or a ‘ : ‘. and the sun graph (fig. 7) sometimes struggles when night doesn’t start until the morning (like at Finse, in summer). ↩︎


#project #dataviz #python #astro