Sonnenstandsdiagramm mit skyfield in Python berechnen & plotten
English
Deutsch
In diesem Beispiel zeigen wir, wie man ein Sonnenstandsdiagramm für einen beliebigen Tag für einen vorgewählten Standort generiert. Durch die Verwendung der skyfield-Bibliothek können wir extrem genaue Vorhersagen der Sonnenposition am Himmel erhalten, und im Gegensatz zu vielen anderen Bibliotheken können wir dieselbe Methode verwenden, um die Position anderer Himmelskörper vorherzusagen.
sun_path_plot.py
#!/usr/bin/env python3
from skyfield import api
from skyfield import almanac
from datetime import datetime
from datetime import timedelta
from matplotlib import pyplot as plt
import pytz
import dateutil.parser
from collections import namedtuple
from UliEngineering.Utils.Date import *
import matplotlib.ticker as mtick
# Matplotlib-Formatter
def format_degrees(value, pos=None):
return f'{value:.0f} °'
ts = api.load.timescale()
ephem = api.load_file('de421.bsp')
sun = ephem["Sun"]
earth = ephem["Earth"]
# Datentypen
AltAz = namedtuple("AltAz", ["altitude", "azimuth", "distance"])
TimeAltAz = namedtuple("TimeAltAz", ["time", "altitude", "azimuth", "distance"])
def sun_altaz(planet_at_location, ts):
# Sonnenposition vom Beobachter an <location> berechnen
sun_pos = planet_at_location.at(ts).observe(sun).apparent()
# Scheinbare Höhe & Azimut für die Sonnenposition berechnen
altitude, azimuth, distance = sun_pos.altaz()
return AltAz(altitude, azimuth, distance)
def sun_altaz_for_day(location, year, month, day, tz):
earth_at_location = (earth + location)
minutes = list(yield_minutes_on_day(year=year, month=month, day=day, tz=tz))
skyfield_minutes = ts.from_datetimes(minutes)
minutely_altaz = [sun_altaz(earth_at_location, ts) for ts in skyfield_minutes]
# Komponenten zum Plotten extrahieren
minutely_alt = [altaz.altitude.degrees for altaz in minutely_altaz]
minutely_az = [altaz.azimuth.degrees for altaz in minutely_altaz]
minutely_distance = [altaz.distance for altaz in minutely_altaz]
return TimeAltAz(minutes, minutely_alt, minutely_az, minutely_distance)
# Zufälliger Standort in der Nähe von München
location = api.Topos('48.324777 N', '11.405610 E', elevation_m=519)
# Alt/Az für zwei verschiedene Tage berechnen
jun = sun_altaz_for_day(location, 2022, 6, 15, pytz.timezone("Europe/Berlin"))
dec = sun_altaz_for_day(location, 2022, 12, 15, pytz.timezone("Europe/Berlin"))
# Plotten!
plt.gca().yaxis.set_major_formatter(mtick.FuncFormatter(format_degrees))
plt.gca().xaxis.set_major_formatter(mtick.FuncFormatter(format_degrees))
plt.plot(jun.azimuth, jun.altitude, label="15. Juni")
plt.plot(dec.azimuth, dec.altitude, label="15. Dezember")
plt.ylim([0, None]) # Sonnenwinkel unter dem Horizont nicht anzeigen
plt.ylabel("Sonnenhöhe")
plt.xlabel("Sonnenazimut")
plt.title("Scheinbare Sonnenposition an unserem Büro")
plt.grid()
plt.gca().legend()
plt.gcf().set_size_inches(10,5)
plt.savefig("Sun path.svg")If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow