Comment calculer & tracer un diagramme du chemin du soleil en utilisant skyfield en Python

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.

Diagramme du chemin du soleil

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")

Consultez les articles similaires par catégorie : Physique Python Skyfield