Skyfield
Skyfield is an elegant Python library for high-precision astronomy calculations. It allows users to compute the positions of planets, satellites, stars, and other celestial bodies from any point on Earth or in space, at any moment in time. It leverages JPL ephemeris data to achieve high accuracy. It's actively maintained with regular releases, often several per year, reflecting ongoing development and bug fixes.
Warnings
- gotcha Skyfield requires large ephemeris data files (e.g., `de421.bsp`). These files are downloaded on first use when `load('filename.bsp')` is called. This requires an active internet connection and write permissions to the data directory (typically `~/.skyfield/data`). In environments without internet or write access, this will fail.
- gotcha Since Skyfield 1.36, the `radec()` and `altaz()` methods on observation objects return a dedicated object (e.g., `_Astrometric`) rather than a simple 3-tuple. While Python's sequence unpacking (`ra, dec, distance = obs.radec()`) still works, directly accessing values by index (e.g., `obs.radec()[0]`) will fail, as the returned object is not a `tuple`.
- gotcha Skyfield uses its own precise `Time` objects, which are crucial for accurate astronomical calculations and handle leap seconds, TAI, TT, and UTC correctly. Mixing these with naive Python `datetime` objects or incorrectly converting timezone-aware `datetime` objects can lead to subtle but significant errors due to differences in time scales, daylight saving time, or floating-point precision.
Install
-
pip install skyfield
Imports
- load
from skyfield.api import load
- Topos
from skyfield.api import Topos
- ts
from skyfield.api import load; ts = load.timescale()
Quickstart
from skyfield.api import load, Topos
# Load the ephemeris data; downloads if not present.
eph = load('de421.bsp')
# Get the timescale object for precise time calculations.
ts = load.timescale()
# Define an observer's location (e.g., Greenwich, UK)
greenwich = Topos(latitude_degrees=51.478, longitude_degrees=0.0)
# Define a specific moment in time (UTC)
t = ts.utc(2024, 12, 25, 12, 0, 0) # Christmas Day 2024, Noon UTC
# Observe Mars from Earth, as seen from Greenwich
astrometric = greenwich.at(t).observe(eph['mars'])
# Get the astrometric position (Right Ascension, Declination, Distance)
ra, dec, distance = astrometric.radec()
print(f"Time (UTC): {t.utc_datetime()}")
print(f"Mars Right Ascension: {ra}")
print(f"Mars Declination: {dec}")
print(f"Distance to Mars: {distance}")