Skip to main content

Command Palette

Search for a command to run...

Daylight on a globe earth

Updated
5 min read

This is about a github project https://github.com/jamesdogrady/sunGleason.

Sometimes, I’ll click on YouTube videos that debunk the flat earth theory. One common map used in this theory is the so called Gleason map, from the late 1800s which looks like this.

The map has many problems, but its youtube plausible since you can travel west or east around the map without falling off the edge, unlike other maps. To fall off the edge, you have to travel to interior Antartica which is more possible now, but was out of reach when the map was published. Sometimes, when showing this map, someone will show how the sunlight works on this map with a flashlight and in fact, it doesn’t. I wanted to show that and cartopy in python lets you do that, which is what the project is about.

This map is a Azimuthal Equidistant projection of the globe with the center at the north pole. This is one of the projections offered by cartopy.crs, so we can show a similar map very easily.

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

proj=ccrs.AzimuthalEquidistant(central_latitude=90, central_longitude=-90);
ax = plt.axes(projection=proj)
ax.set_global()
ax.coastlines()
ax.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5)
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.add_feature(cfeature.LAND, facecolor='lightgray')
ax.add_feature(cfeature.OCEAN, facecolor='lightblue')

# Chicago IL
lat=41.8781
long=-87.6298
ax.plot(long,lat,'o',markersize=10,transform=ccrs.PlateCarree(),color='red');
plt.show()

Central latitude is 90 for the North Pole. We use the central longitude of 90 W to replicate the engraving. Western longitudes and southern latitudes are negative. The location of Chicago is plotted on the map with too large of a circle (The ‘o’ in ax.plot). The result looks like this.

To show the daylight, we’ll use the astral package for python. This package allows you to calculate sunrise and sunset based on latitude and longitude. We’ll mark each point with a different color depending on whether it’s day or night. There are two approaches here. I chose to use astral to calculate whether it’s day or night in individual locations. It’s probably better to calculate the lines that separate day and night and draw polygons to show this. I think using sunrise/sunset is more verifiable since the times are widely available, for instance in local newspapers.

Note that north of the Arctic Circle and south of the Antarctic Circle, 24 hour night and day is possible. This causes the astral.sun.sunrise and astral.sun.sunset to throw an exception. The text of the exception tells you whether it’s night or day. Essentially, the code for the daylight check looks like this.

import pytz
utc= pytz.UTC
from astral import Observer
from astral.sun import sunrise,sunset
from astral.sun import zenith
from shapely.geometry import Point 
# p is a Point, date is the date
def is_day(p,date) :
    obs = Observer(p.y,p.x)
    try :
        rise_time = sunrise(obs,date).replace(tzinfo=utc)
        set_time = sunset(obs,date).replace(tzinfo=utc)
    except  ValueError as e:
        # 24 hour sun
        if "above" in e.text() :
            return True
        else :
            # 24 hour night.
            return False    
    if ( rise_time > set_time ) :
        # the period of light crosses a day boundary.  the sun will be up between midnight
        # and set_time, down between set_time and rise_time and up after rise_time.
        if ( date < set_time ) :
            return True
        if ( date >= rise_time ) :
            return True;
        return False
    # here, rise_time < set_time
    if ( date >= rise_time and date < set_time) :
        return True;
    else :
        return False;

What remains now is just to plot points. Here, we are using circles ( parameter “o”). The size of the circle is marker_size and it’s transparency is alpha which is point_alpha. These are configurable in the actually application.

if ( is_day(p,date ) :
    color="yellow"
else :
    color="black"
ax.plot(p.x,p.y,'o', markersize=marker_size, transform=ccrs.PlateCarree(),color=color,alpha=point_alpha)

You can add a title to the plot using

ax.set_title(date.strftime("%m/%d/%Y %H:%M" + " UTC"));

We may want to add text to the bottom of the plot as well, but the coordinates make this tricky in this projection system. This puts text off to the side on the button away from the labels. This isn’t in the github.

lon_min, lon_max, lat_min, lat_max = ax.get_extent()
ax.text( (lat_max-lat_min)/2,lon_min-30, "some text, ha='left', fontsize=12,transform=self.proj)

The defaults here are an alpha of .01, a markersize of 1 and plotting points every degree. For the summer solstice, June 20, 2025 at 9:41 PM CDT, you get a picture like this.

The Orange dot here is the point with the lowest zenith amount the points looked at. This is roughly where the sun is overhead.

To check the visualization, you can look at other web visualizations, for instance, that of timeanddate.com for the same time which looks like this:

If one looks at the github, there’s more going on that what’s described here. The whole application is a Python QT application. I don’t cover that because it’s just how you’d wrap matplotlib into a python qt application which others cover already and what I want to cover is integrating daylight into a Gleason map. Also, some of the glue here is from ChatGPT which to be fair also pointed me toward cartopy when I had started with geopandas.

There is a preferences dialog also, which is also basically also from ChatGPT. You can specify the size and transparency of how the day or night markers are shown. You can also update the latitude and longitude the project is centered on. As you do this, you move off of the Gleason map, but visualizing the projection centered on where the sun is overhead is useful. I also allow you to specify a distance between latitudes and longitudes that are plotted. This allows you to draw pictures much more quickly, but the visualization isn’t as good. The defaults don’t show the individual points but spreading out the interval makes the points show up, e..g.

uses 5 degrees apart and plot much fewer points more quickly, but the points show up and more of the underlying plot is exposed between the points and it’s harder to see the shape daylight or nighttime make on the map..

This is not a fully fleshed out application. Much more could be done, but this has a pretty limited utility. The earth is not flat, so this is not a map of the earth and the drawings the application makes of daylight are not real so it’s unclear beyond what it already does how much more time is useful to spend on this.