DEV Community

balyakin
balyakin

Posted on

Building SkyMoment: A 4K Personalized Star Map Generator with Python, Skyfield and Astronomical Data

Building SkyMoment: A 4K Personalized Star Map Generator with Python, Skyfield and Real Astronomical Data

I recently shipped a small side project called SkyMoment — a generator that creates personalized 4K star map posters using real astronomical data.

You enter a date, time, and location.

SkyMoment recreates the exact night sky for that moment and renders it as a minimalist, print-ready 4000×4000 poster.

🔗 Live demo: https://skymoment.art/

This post is a breakdown of how the system works — from astronomical calculations to rendering and backend automation.


🌌 The idea

Most “star map posters” online aren’t actually based on real sky data.

Many use approximations, fake constellations, or pre-rendered visuals.

I wanted something more accurate and scientific:

  • real positions of stars,
  • real coordinate transforms,
  • proper field of view,
  • natural-looking Milky Way,
  • clean and minimal layout.

And I wanted to turn this into a small automated product:

enter a moment → get a PDF/PNG → done.


🛰 Tech stack overview

Python — main rendering pipeline

Skyfield — planetary ephemeris & star calculations

Hipparcos catalog — star positions & magnitudes

Astropy — coordinate transforms

Matplotlib — final 4K rendering

Django — backend & API

Lemon Squeezy — payments + webhooks

SMTP — email delivery of the final poster

The frontend is intentionally minimal. The “magic” happens in the rendering pipeline.


🔭 Astronomical calculations step-by-step

When a user enters:

  • date
  • time
  • location (lat/lon)

the pipeline does:

1. Convert local time to UTC

Skyfield requires accurate UTC timestamps.

2. Load planetary ephemeris

Using DE421 / DE422 depending on the build.

3. Load Hipparcos star catalog

This gives:

  • RA/Dec
  • magnitude
  • proper motion

4. Transform everything into the user's sky coordinates

Using Astropy AltAz transforms based on the observer’s position.

5. Filter stars

Only stars above a certain brightness threshold are rendered.

6. Split bright/faint stars

Bright stars use a stylized 8-point marker.

Faint stars use simple dots.

7. Render the Milky Way

A custom multi-noise layer:

  • low-frequency shapes
  • medium cloud structure
  • smooth alpha falloff
  • suppression of “sand grain” artifacts

This part took the longest to tune.

8. Render at 4000×4000 resolution

Matplotlib actually does a great job when used carefully.

Total render time: ~35–40 seconds on server hardware.


🖥 Rendering performance challenges

4K resolution + thousands of stars + Milky Way noise layers = heavy.

Some optimizations:

  • preload catalogs once per worker
  • reuse figure objects
  • avoid expensive Python loops
  • limit use of transparency
  • skip stars below a certain magnitude
  • cache static layers when possible

Even small changes can save 10–20% time.


🧩 Backend architecture (Django)

SkyMoment uses a simple pipeline:

1. User configures their moment

Chooses date/time/location and sees a preview.

2. User is redirected to Lemon Squeezy checkout

3. After payment, LS sends a webhook to Django

The webhook contains:

  • the order ID
  • the custom fields (title, location, datetime)
  • the product variant

4. Django creates a generation job

Status: pendinggeneratingready

5. A worker process runs the Python renderer

6. The final 4K poster is saved to disk

7. Django sends an email with a download link

Important detail:

the webhook responds immediately — rendering happens asynchronously to avoid LS timeouts.


🧪 Example of what the system produces

Here is a reduced-size preview of a generated poster:

(Insert image URL here if you want)

The 4K version includes:

  • precise star positions
  • constellation lines
  • minimal typography
  • custom title & subtitle
  • a clean dark theme

🚀 What’s next

On the roadmap:

  • multiple poster templates
  • faster rendering (possibly caching or partial reuse)
  • more curated landing pages
  • detailed generational logs and analytics

If you want to try generating a star map for your own moment:

🔗 https://skymoment.art/

Happy to answer any technical questions about astronomical data, rendering, or backend architecture!

Top comments (0)