V tomto příkladu ukážeme, jak vygenerovat diagram cesty slunce pro kterýkoliv den pro předem vybrané místo. Pomocí knihovny skyfield můžeme získat extrémně přesné předpovědi pozice slunce na obloze, a na rozdíl od mnoha dalších knihoven, můžeme použít stejnou metodu pro předpověď pozice dalších nebeských těles.
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
# Formátovač pro Matplotlib
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"]
# Datové typy
AltAz = namedtuple("AltAz", ["altitude", "azimuth", "distance"])
TimeAltAz = namedtuple("TimeAltAz", ["time", "altitude", "azimuth", "distance"])
def sun_altaz(planet_at_location, ts):
# Vypočítat pozici slunce, jak je vidět od pozorovatele v <location>
sun_pos = planet_at_location.at(ts).observe(sun).apparent()
# Vypočítat zjevnou výšku a azimut pro pozici slunce
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]
# Extrahovat komponenty pro vykreslení
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)
# Náhodné místo poblíž Mnichova
location = api.Topos('48.324777 N', '11.405610 E', elevation_m=519)
# Vypočítat Alt/Az pro dva různé dny
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"))
# Vykreslit!
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. června")
plt.plot(dec.azimuth, dec.altitude, label="15. prosince")
plt.ylim([0, None]) # Nezobrazovat úhly slunce pod horizontem
plt.ylabel("Výška slunce")
plt.xlabel("Azimut slunce")
plt.title("Zjevná pozice slunce v naší kanceláři")
plt.grid()
plt.gca().legend()
plt.gcf().set_size_inches(10,5)
plt.savefig("Sun path.svg")Pokud vám tento článek pomohl, zvažte, zda mi nekoupíte kávu nebo nepřispějete přes PayPal na podporu výzkumu a publikování nových článků na TechOverflow