from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from skyfield.api import load
from skyfield.data import mpc
from skyfield.constants import GM_SUN_Pitjeva_2005_km3_s2 as GM_SUN
from starplot import (
HorizonPlot,
PlotStyle,
style_extensions,
Constellation,
Observer,
_,
)
# First, we use Skyfield to get comet data
# Code adapted from: https://rhodesmill.org/skyfield/kepler-orbits.html#comets
with load.open(mpc.COMET_URL) as f:
comets = mpc.load_comets_dataframe(f)
# Keep only the most recent orbit for each comet, and index by designation for fast lookup.
comets = (
comets.sort_values("reference")
.groupby("designation", as_index=False)
.last()
.set_index("designation", drop=False)
)
# Find Comet C/2025 A6 (Lemmon)
# Values at time of publishing (2025-OCT-15):
# CK25A060 2025 11 8.5383 0.529888 0.995631 132.9700 108.0979 143.6635 20251013 13.2 4.0 C/2025 A6 (Lemmon)
row = comets.loc["C/2025 A6 (Lemmon)"]
# Load timescale and ephemeris
ts = load.timescale()
eph = load("de421.bsp")
sun, earth = eph["sun"], eph["earth"]
comet = sun + mpc.comet_orbit(row, ts, GM_SUN)
# October 17 @ 6:30pm PT (about 20min after sunset)
tz = ZoneInfo("US/Pacific")
dt = datetime(2025, 10, 17, 18, 30, 0, 0, tzinfo=tz)
# Find the RA/DEC of comet for every other day starting on October 17, 2025
radecs = []
for day in range(0, 22, 2):
dt_current = dt + timedelta(days=day)
t = ts.from_datetime(dt_current)
ra, dec, distance = earth.at(t).observe(comet).radec()
radecs.append((dt_current, ra.hours * 15, dec.degrees))
# Now let's plot the data on a map!
style = PlotStyle().extend(
style_extensions.BLUE_DARK,
style_extensions.GRADIENT_BOLD_SUNSET,
style_extensions.MAP,
)
# Create observer for October 21 @ 6:30pm PT (about 20min after sunset)
observer = Observer(
dt=datetime(2025, 10, 21, 18, 30, 0, 0, tzinfo=tz),
lat=33.363484, # Palomar Mountain, CA
lon=-116.836394,
)
p = HorizonPlot(
altitude=(0, 55),
azimuth=(220, 320),
observer=observer,
style=style,
resolution=3000,
scale=1,
hide_colliding_labels=False,
)
# Plot the comet markers
for t, ra, dec in radecs:
label = f"{t.month}/{t.day}"
p.marker(
ra=ra,
dec=dec,
style={
"marker": {
"size": 38,
"symbol": "comet",
"fill": "full",
"color": "hsl(183, 100%, 80%)",
"edge_color": "hsl(183, 100%, 80%)",
"alpha": 1,
"zorder": 4096,
},
"label": {
"anchor_point": "top right",
"font_size": 28,
"font_weight": "bold",
"font_color": "hsl(60, 70%, 72%)",
"zorder": 4096,
"offset_x": "auto",
"offset_y": "auto",
},
},
label=label,
)
boo = Constellation.get(iau_id="boo")
p.horizon()
p.constellations(where=[_.iau_id.isin(["boo"])], style__alpha=0.75, style__width=1.8)
p.stars(
where=[_.hip.isin(boo.star_hip_ids) | (_.name == "Antares")],
where_labels=[_.magnitude < 2],
style__label__font_size=30,
)
p.constellation_labels(style__font_alpha=1)
p.export("plot.svg", format="svg")