Like many projects, this one was abandonned for a while.
But it’s (mostly) done now.
solarigraphy
Solarigraphy is the photographic practice of using a pinhole camera to capture an image of the sun’s path over days-weeks-months-years. Typically it uses regular B&W photo paper[1] for capturing the image. And processing is gloriously simple: scan the image, invert it left-to-right, and invert the colours. No red-light or chemistry required.
I’ve had a handful of successful attempts, and just as many unsuccessful ones[2]. The unsuccessful, along with my impatience at waiting six months, motivated me to write some wobbly code to simulate these.
To model a solarigraph we need (a) coordinates and (b) dates. From those we can generate the sun’s path; get hold of some whether data; determine what the horizon looks like. Then cobble them together into a single plot.
Onwards.
the sun’s path
Every day the sun draws a smooth curve across the sky that a well-placed solarigraph is primed to capture. First, a brief refresher on what the sun does…
In the northern hemisphere, at some point in March and at another point in September, the sun rises in the East, and gradually climbs to its zenith[3] while moving round towards the South, after which it descends and moves to the West, before then falling behind horizon at sunset (Fig 0).
In summer:
- sunrise is north of east
- the zenith is a bit higher in the sky
- sunset is north of west
- this takes longer, and so the days are longer
In winter:
- sunrise is south of east
- the zenith is lower, i.e. the sun never gets too far above the horizon
- sunset is south of west
- this shorter path doesn’t take so long, and the days are short and miserable
Just how high, and how north of west, very much depends on one’s latitude.
Another thing that depends on one’s latitude and longitude, is what the horizon looks like…
the horizon
At sea, or in the Netherlands, the horizon appears to be a straight line. In the heart of the Dolomites or in a dense urban area, the horizon - that line where the sky stops and land and buildings and trees start - is not straight (Fig 1).
Sometimes, as I’m sure you’ve seen, the sun is very much above the horizon in the sense that it is daytime, but you also can’t see it, it is below your own personal horizon. Or in the case of a distant mountain, the sun is above the nautical horizon, but below the topographic horizon.
Again, a well placed solarigraph can handle this. And so must a simulated one.
Another thing that influences whether or not one can see the sun…is the weather.
the weather
Because this is a realistic[4] simulation, it relies on weather observations not forecasts. Open-Meteo provide a historical weather API,[5] which can provide hourly measurements of total cloud cover (as a fraction between 0 and 1) from 1940-yesterday over a 0.25° grid. And, in the spirit of choosing-the-path-of-least-resistance, we’ll use the cloud cover fraction to vary the opacity of the sun paths (Fig 2).
projecting
The above figures have all plotted both solar elevation, , and solar azimuth, , in degrees on a linear scale, from North all the way back round to North. But, what goes on inside a, cylindrical with radius ,[6] pinhole camera isn’t linear. So we need to map solar azimuth and elevation to paper-inside-the-camera coordinates.[7]
Left-to-right is reasonably straightforward, although this took me longer than I care to admit to wrap my head around.
This is a linear relationship.
For a pinhole camera facing due south (180°, ) only light originating from the east (90°, ) round to the west (270°, ) are theoretically capable of entering the camera. The length of paper inside the camera is .
The above equations maps east to , and west to , for a total span of . In reality, however, a field of view of ~150° is more reasonable. Additionally, a bit of modular arithmetic allows us to point the pinhole in whatever direction, , we fancy
Up-and-down is a bit more involved, since the horizontal component, , of the distance from the pinhole to the paper depends on the azimuth
and the resulting vertical distance from the pinhole, , is a function of both elevation and azimuth
This projection process gives rise to a few, let’s call them, features (Fig 3). Irrespective of how far beyond the camera’s azimuth range sunrise/set actually is, the projected image gives the impression of a sunrise/set at the edges of this range. This is because at these extremes , and so, regardless of the solar elevation, , the in paper-coordinates goes to zero. This gives the apperance of solar paths at different times of year converging to a point.
Another quirk, is that terrain is more subdued — less dramatic, especially away from the centre. In Fig 3 this can be seen in the two peaks in the south-west that are at approximately the same elevation angle (the more western one is slightly lower) in the unprojected image, but once projected the more western one is markedly lower, and less peak-y.
This is a problem with . And it is particularly evident at tropical latitudes where solar elevations can sneak up to 90°,[8] and is kind of undefined. So, in these simulated solarigraphs there is a need to clip the elevations to something sensible, like 76°, or .[9]
styling
Firstly, move the azimuth axis and the cardinal[10] points the top. Secondly, borrow the colours for land, sky and sun from the small handful of real solarigraphs that I’ve made.[11] And tah-dah, you can now pick your theme and see the output in Fig 4.
Oh, and, add some credits for the data sources and me[12], and perhaps a title with the coordinates and time range being shown.
bundling
cli
At first I thought I’d bundle my code up in such a way that someone could use pipx to install the a little cli. I used typer for this. And well, that is a thing that can be done…
installation
- ensure
python3.14or greater is installed. See python installation instructions - check
pipxis installed: Pipx installation guide - to install solarigraph:
pipx install --python python3.14 git+https://codeberg.org/tlohde/solarigraphy.git
solarigraph is now installed.
usage
Run with the following command: solarigraph make. See solarigraph make --help for a full list of arguments and options. Do not be scared of all the parameters, I have tried to give most of them sensible defaults. For example…
solarigraph make 63.83034 -50.06830 2026-04-01 2026-05-30 --facing 90
will output a file named something like sgraph_63.83-50.06.png which should give you a glimpse into early spring at Isortuarsuup Sermia.
api
Now we’re cooking. It was reasonably straightforward to set up a fastAPI, and so if you don’t feel like downloading it yourself — no bother.
The fiddly thing, for me at least, was the requisite JS for the below.
Will this work in every instance. Probably not.
There is some validation here:
- latitude and longitude should be, valid, y’know.
- start date must be after 1st Jan 1940
- start date should be before the end date
- end date should be after the start date
- end date should be yesterday or before
- facing should be a number. Between 0 and 360.
- radius shouldn’t really be bigger than 50.
Click a point on the map; select some dates,[13] and which way you’re looking[14]; and how far you want to search for the horizon[15]
conclusion?
It’s worth saying that, as usual Darling Reader, this exercise was more[16] for me. If you enjoyed some of it—any of it—I am thrilled. Truly. But it was mainly for me to play and learn some stuff.
And I played and I learnt some stuff.
Is it perfect. Nope. Are there a bucket-load of edge-cases that bork the whole enterprise. Yep.
And post.
footnotes
the sort used to make B&W prints in a dark room ↩︎
for reasons unknown, or some busy-body taking it off the lamppost-or-whatever I lashed it to ↩︎
it’s highest point in the sky on a given day ↩︎
whatever that means ↩︎
using ERA5 reanalysis data ↩︎
let for convenience, y’know ↩︎
and start working in radians ↩︎
there’s a cool name for it: Lāhainā Noon ↩︎
no reason other than I tried a few values, and across a few latitudes and this seemed good enough ↩︎
and intercardinal ↩︎
and, I should probably make a few more palettes ↩︎
because
i’m fabulousI made the damn thing ↩︎maybe from one solstice to the next ↩︎
0: North; 90: East; 180: South; 270 West. And everything in between ↩︎
don’t bother going over 50 ↩︎
wholly ↩︎