Dans cet exemple, nous allons montrer comment générer un diagramme du chemin du soleil pour n’importe quel jour donné pour un emplacement présélectionné. En utilisant la bibliothèque skyfield, nous pouvons obtenir des prédictions extrêmement précises de la position du soleil dans le ciel, et contrairement à beaucoup d’autres bibliothèques, nous pouvons utiliser la même méthode pour prédire la position d’autres corps célestes.
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
# Formateur 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"]
# Types de données
AltAz = namedtuple("AltAz", ["altitude", "azimuth", "distance"])
TimeAltAz = namedtuple("TimeAltAz", ["time", "altitude", "azimuth", "distance"])
def sun_altaz(planet_at_location, ts):
# Calcule la position du soleil vue par l'observateur à <location>
sun_pos = planet_at_location.at(ts).observe(sun).apparent()
# Calcule l'altitude & l'azimut apparents pour la position du soleil
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]
# Extract components for plotting
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)
# Emplacement aléatoire près de Munich
location = api.Topos('48.324777 N', '11.405610 E', elevation_m=519)
# Calcule Alt/Az pour deux jours différents
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"))
# Trace !
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="15th of June")
plt.plot(dec.azimuth, dec.altitude, label="15th of December")
plt.ylim([0, None]) # Ne pas montrer les angles du soleil sous l'horizon
plt.ylabel("Altitude du soleil")
plt.xlabel("Azimut du soleil")
plt.title("Position apparente du soleil à notre bureau")
plt.grid()
plt.gca().legend()
plt.gcf().set_size_inches(10,5)
plt.savefig("Sun path.svg")Si cet article vous a aidé, pensez à m'offrir un café ou à faire un don via PayPal pour soutenir la recherche et la publication de nouveaux articles sur TechOverflow