Lunar month and Moon phases with Python
In this tutorial, I will explain how to make a video of one lunar month, where the Moon goes around the Earth and shows all its phases. This time I will not give the full code. The program behind this video is quite big, so I will focus on the principles, and you can use them in your own program with any tools you like.
This article continues my previous tutorials. In Spinning Earth animation with Python, I showed how to wrap a flat map around a sphere and light it by the Sun. In the article about ephemerides, I explained where the exact positions of the planets and the Moon come from. And in Moon and Earth epicycloid, we looked at the motion of the Moon together with the Earth around the Sun. Now we will put all these ideas together.
What are Moon phases
The Moon does not shine by itself. It is a dark rocky ball, and one half of it is always lit by the Sun, exactly like the Earth has day and night. What changes during a month is not the Moon, but our point of view. When the Moon goes around the Earth, we see a different part of its lit half, and this is what we call the Moon phase.
The phase depends only on one angle - the angle between the Sun and the Moon as seen from the Earth. Astronomers call it elongation. When the Moon is in the same direction as the Sun, its lit side faces away from us. When the Moon is on the opposite side of the Earth, we see the whole lit half.
Eight phases
The Moon is in its waxing crescent phase, with approximately 37% of its visible surface illuminated by the Sun. It is approaching the First Quarter, when half of the Moon's visible disc will be illuminated. As the Moon orbits Earth, the illuminated fraction increases each day, bringing it closer to the First Quarter phase.
Original image: 2160 x 1756
Usually we name eight phases. Four of them are exact moments, and four are periods between them.
New Moon - the Moon is between the Earth and the Sun, and we see only its dark side. It is in the sky together with the Sun, so we cannot see it at all.
Waxing crescent - a thin lit edge appears in the western sky after sunset. "Waxing" is an old English word for growing.
First Quarter - exactly half of the disc is lit, and the Moon is 90° away from the Sun. It is highest in the sky at sunset and sets around midnight. The name is a bit confusing: it is called a quarter because the Moon has made a quarter of its cycle, not because a quarter of the disc is lit.
Waxing gibbous - more than half of the disc is lit, and the lit part keeps growing. "Gibbous" comes from the Latin word for hump.
Full Moon - the Moon is opposite the Sun, and we see the whole lit side. It rises at sunset and stays in the sky all night.
Waning gibbous - the lit part begins to shrink. "Waning" means getting smaller.
Last Quarter (also called Third Quarter) - half of the disc is lit again, but now it is the other half. The Moon rises around midnight and is visible in the morning.
Waning crescent - a thin edge in the morning sky before sunrise, and then a New Moon again.
In the Northern Hemisphere, the growing Moon is lit on the right side and the shrinking Moon on the left. In the Southern Hemisphere, everything is the opposite, because people there see the Moon upside down.
Lunar month
From one New Moon to the next, there are on average 29.53 days. This is called the synodic month, and the number of days since the last New Moon is called the age of the Moon. But if we measure one full turn of the Moon relative to the stars, we get only 27.32 days - the sidereal month.
Where do the two extra days come from? During one month, the Earth moves around the Sun by about 27°, so the Moon needs to go a little bit further to come back to the same position relative to the Sun. This is a nice example of how the motion of the Earth around the Sun and the motion of the Moon around the Earth add together, as we saw in the epicycloid article.
How to make a video of the lunar month
Now let's see how to make the video. The main idea is very simple: we do not draw the phases at all! We only put the Sun, the Earth and the Moon at their real positions and light them by the Sun, and the phases appear by themselves, exactly as in real life. This is the most important idea of this article!
Time and frames
A video is just a list of frames, and every frame is one moment of time. For example, if we want to show 30 days in a 30-second video at 30 frames per second, we need 900 frames, and every next frame is 48 minutes later than the previous one.
Every frame is calculated independently from scratch: we take its date, calculate all positions, draw the picture and save it as a PNG file. This sounds like extra work, but it gives big advantages. Frames can be calculated in parallel on all processor cores, in any order, and if the program is interrupted, it can continue from the last saved frame. At the end, all frames are joined into an MP4 video with ffmpeg.
Positions of the Sun, the Earth and the Moon
For every frame, we need the positions of three bodies. I take them from the JPL ephemeris DE440, as I described in the article about ephemerides. All positions are in astronomical units, in the J2000 ecliptic frame, relative to the centre of mass of the Solar System. JPL files store the Earth and the Moon relative to their common centre of mass (the Earth-Moon barycentre), so it is very easy to get the position of the Moon relative to the Earth.
If ephemeris files are not available, it is possible to use approximate formulas (an analytic Moon theory). It is good enough for a nice picture, but for exact phase times the ephemeris is much better.
Point of view
Next step - we need to decide where our camera is. For a lunar month, I think the best view is from above the Earth, looking down at the plane of the Moon's orbit.
The second question is: what is fixed on the screen? If the stars are fixed, the direction to the Sun slowly turns by about 30° during the month. It is much better to keep the Sun in a fixed direction on the screen, for example always on the left. Then the lit sides of the Earth and the Moon always face the same side of the picture, and it is very easy to see how the phase depends on the position of the Moon. In this view, the Moon makes exactly one full turn from New Moon to New Moon. It is also interesting to do the opposite and keep the Moon fixed on the screen.
Proportions
Here we have a problem. The Moon is about 384,400 km away from the Earth, which is about 30 Earth diameters, and the Moon's diameter is only 27% of the Earth's diameter. If we fit the whole Moon orbit into a 1080-pixel-wide picture, the Earth will be only about 15 pixels and the Moon only about 4 pixels.
That is why I use one number to control proportions. With PROP = 0 everything is real, and with PROP = 1 we have textbook proportions: sizes are compressed by a power law, and the Moon's distance is compressed around the Earth, so the Moon always stays outside the enlarged Earth. Between 0 and 1 the values are blended geometrically, so a change of PROP looks like a smooth zoom.
Lighting and textures
For the Earth, we use the same method as in the spinning Earth tutorial. For every pixel, we find the point on the sphere, then its latitude and longitude, then the colour from the map, and finally the brightness by Lambert's cosine law. The full program goes further: it is a small ray tracer written in NumPy, where every pixel is subsampled for smooth edges, and the Earth has clouds, city lights on the night side, a sun glint on the oceans and a blue atmosphere rim.
For the Moon, Lambert's law does not work well. The real Full Moon looks like a flat disc, almost equally bright up to its edge, because the dusty lunar surface reflects light differently. So the Moon uses a special lunar reflection model (for example, the Lommel-Seeliger law), which gives this flat look. All light is calculated in linear brightness and then converted with a filmic tone curve, so the bright day side and the dark night side both look good in one picture.
Rotation
The Earth needs the correct direction of its axis and the correct time of day. The official IAU rotation models give both, including the 23.4° tilt of the Earth's axis. But there is one problem: with 48 minutes between frames, the Earth turns by 12° per frame, and such a fast rotation flickers in a video. So when a body spins faster than about 10° per frame, its rotation is shown slowed down.
The Moon always shows the same side to the Earth, because it is tidally locked. So its orientation is calculated from its real orbit around the Earth. In fact, the Moon wobbles a little bit (this is called libration), and over time we can see about 59% of its surface. The phase panel described below ignores this small effect.
Calculating the phase
For labels and the phase panel, we need numbers, and all of them come from the three positions. Here is the idea in a few lines, where sun, earth and moon are position vectors from the ephemeris:
to_sun = sun - earth # vectors from the centre of the Earth
to_moon = moon - earth
cos_e = np.dot(to_sun, to_moon) / (np.linalg.norm(to_sun) * np.linalg.norm(to_moon))
lit = (1 - cos_e) / 2 # fraction of the Moon's disc lit by the Sun
dlon = np.degrees(np.arctan2(to_moon[1], to_moon[0]) - np.arctan2(to_sun[1], to_sun[0])) % 360cos_e is the cosine of the elongation, and (1 - cos_e)/2 gives the lit part of the disc: 0 at New Moon, 0.5 at the quarters and 1 at Full Moon. dlon is the difference between the ecliptic longitudes of the Moon and the Sun. The official definition of the four main phases uses exactly this angle: 0° is New Moon, 90° is First Quarter, 180° is Full Moon and 270° is Last Quarter. If dlon is less than 180°, the Moon is waxing, otherwise it is waning. In a program, it is convenient to give the four main names to a small range around these angles and use the in-between names for the rest of the time.
The age of the Moon can be estimated as dlon/360 × 29.53 days, but this estimate can be wrong by more than half a day, because the Moon moves faster when it is close to the Earth and slower when it is far. For the exact age, we need to find the moment of the last New Moon, when dlon was equal to 0.
With these numbers, the program shows the phase name, the percentage lit and the age of the Moon next to it. Also, there is a fixed panel with a large Moon, drawn from the lunar texture and lit as seen from the Earth. So in the main picture we see the geometry, and in the panel we see the result, as we see it in the sky.
Track of the Moon
To see the motion better, the Moon leaves a track behind it. This track is not collected from earlier frames. In every frame it is calculated again from the ephemeris, so frames stay independent, and it slowly fades with age. In our view from above the Earth, the track of the Moon is a circle around the Earth. If we look at the same motion from the Sun, the picture becomes completely different, and you can read about it in the Moon and Earth epicycloid article.
Lunar month of October 2026
Let's look at a real example. In October 2026, the main Moon phases are at these times (UTC):
Last Quarter - 3 October, 13:25
New Moon - 10 October, 15:50
First Quarter - 18 October, 16:13
Full Moon - 26 October, 04:12
Last Quarter - 1 November, 20:28
The Full Moon on 26 October is called the Hunter's Moon, because it is the first Full Moon after the Harvest Moon of 26 September.
Every month we have a New Moon and a Full Moon, but not every month we have eclipses. The orbit of the Moon is tilted by about 5° to the orbit of the Earth, so usually the Moon passes above or below the Sun or the Earth's shadow. On 10 October 2026 the Moon passes about 4° from the Sun, so there is no solar eclipse, and on 26 October it misses the Earth's shadow by a similar angle.
Also, the orbit of the Moon is not a perfect circle. In this month, the Moon is farthest from the Earth on 16 October (about 404,600 km) and closest on 28 October (about 364,400 km), so at the end of the month it looks about 11% bigger. With real positions from the ephemeris, all these details appear in the video automatically.
As you can see, the Moon phases are just geometry and sunlight. We put three bodies at their real positions, switch on the Sun, and the program shows exactly what we see in the sky. These are absolutely amazing results! With the same principles, you can make a video of a whole year with correct phases, show a solar eclipse from any place on the Earth, or follow a spacecraft flying around the Moon.
Published: 2026-10-17 08:07:53
Updated: 2026-10-17 08:13:34