SOLARPOSITION
This function computes solar position angles for one or more timestamps at a specified site.
For each timestamp, it returns azimuth, elevation, and apparent zenith using one of pvlib’s solar-position algorithms.
Elevation and zenith are related by:
\mathrm{elevation} = 90^\circ - \mathrm{zenith}
Apparent zenith includes atmospheric refraction and is commonly preferred over true zenith for irradiance modeling.
Excel Usage
=SOLARPOSITION(time, latitude, longitude, altitude, pressure, solarpos_meth, temperature)
time(list[list], required): Timestamp or 2D range of timestamps in ISO8601 format.latitude(float, required): Latitude north of equator (deg).longitude(float, required): Longitude east of prime meridian (deg).altitude(float, optional, default: 0): Site elevation above sea level (m).pressure(float, optional, default: 101325): Atmospheric pressure (Pa).solarpos_meth(str, optional, default: “nrel_numpy”): Solar position algorithm method.temperature(float, optional, default: 12): Ambient temperature used in refraction calculation (deg C).
Returns (list[list]): 2D list with one row per timestamp containing azimuth, elevation, and apparent zenith in degrees, or an error string.
Example 1: Summer midday position at sea level
Inputs:
| time | latitude | longitude | altitude | pressure | solarpos_meth | temperature |
|---|---|---|---|---|---|---|
| 2024-06-20T12:00:00Z | 35 | -120 | 0 | 101325 | nrel_numpy | 12 |
Excel formula:
=SOLARPOSITION("2024-06-20T12:00:00Z", 35, -120, 0, 101325, "nrel_numpy", 12)
Expected output:
| Result | ||
|---|---|---|
| 53.1775 | -8.77273 | 98.7727 |
Example 2: Summer morning position at sea level
Inputs:
| time | latitude | longitude | altitude | pressure | solarpos_meth | temperature |
|---|---|---|---|---|---|---|
| 2024-06-20T06:00:00Z | 35 | -120 | 0 | 101325 | nrel_numpy | 12 |
Excel formula:
=SOLARPOSITION("2024-06-20T06:00:00Z", 35, -120, 0, 101325, "nrel_numpy", 12)
Expected output:
| Result | ||
|---|---|---|
| 329.216 | -24.8381 | 114.838 |
Example 3: Winter midday position at higher altitude
Inputs:
| time | latitude | longitude | altitude | pressure | solarpos_meth | temperature |
|---|---|---|---|---|---|---|
| 2024-12-21T12:00:00Z | 35 | -120 | 100 | 90000 | nrel_numpy | 12 |
Excel formula:
=SOLARPOSITION("2024-12-21T12:00:00Z", 35, -120, 100, 90000, "nrel_numpy", 12)
Expected output:
| Result | ||
|---|---|---|
| 94.7359 | -36.8049 | 126.805 |
Example 4: Row vector of timestamps
Inputs:
| time | latitude | longitude | altitude | pressure | solarpos_meth | temperature | |
|---|---|---|---|---|---|---|---|
| 2024-06-20T12:00:00Z | 2024-06-20T18:00:00Z | 35 | -120 | 0 | 101325 | nrel_numpy | 12 |
Excel formula:
=SOLARPOSITION({"2024-06-20T12:00:00Z","2024-06-20T18:00:00Z"}, 35, -120, 0, 101325, "nrel_numpy", 12)
Expected output:
| Result | ||
|---|---|---|
| 53.1775 | -8.77273 | 98.7727 |
| 105.383 | 61.176 | 28.8148 |
Example 5: Winter morning position at sea level
Inputs:
| time | latitude | longitude | altitude | pressure | solarpos_meth | temperature |
|---|---|---|---|---|---|---|
| 2024-12-21T09:00:00Z | 35 | -120 | 0 | 101325 | nrel_numpy | 12 |
Excel formula:
=SOLARPOSITION("2024-12-21T09:00:00Z", 35, -120, 0, 101325, "nrel_numpy", 12)
Expected output:
| Result | ||
|---|---|---|
| 53.4021 | -72.2847 | 162.285 |
Python Code
Show Code
import pandas as pd
from pvlib.solarposition import get_solarposition as pvlib_get_solarposition
def solarposition(time, latitude, longitude, altitude=0, pressure=101325, solarpos_meth='nrel_numpy', temperature=12):
"""
Calculate solar azimuth, elevation, and apparent zenith for given times and location.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.solarposition.get_solarposition.html
This example function is provided as-is without any representation of accuracy.
Args:
time (list[list]): Timestamp or 2D range of timestamps in ISO8601 format.
latitude (float): Latitude north of equator (deg).
longitude (float): Longitude east of prime meridian (deg).
altitude (float, optional): Site elevation above sea level (m). Default is 0.
pressure (float, optional): Atmospheric pressure (Pa). Default is 101325.
solarpos_meth (str, optional): Solar position algorithm method. Valid options: NREL NumPy, NREL Numba, PyEphem, Ephemeris, NREL C. Default is 'nrel_numpy'.
temperature (float, optional): Ambient temperature used in refraction calculation (deg C). Default is 12.
Returns:
list[list]: 2D list with one row per timestamp containing azimuth, elevation, and apparent zenith in degrees, or an error string.
"""
try:
def flatten_str(data):
if not isinstance(data, list):
return [str(data)]
flat = []
for row in data:
row = row if isinstance(row, list) else [row]
for value in row:
if value == "":
continue
flat.append(str(value))
return flat
times = flatten_str(time)
if len(times) == 0:
return "Error: time array cannot be empty"
dt_index = pd.DatetimeIndex(times)
lat = float(latitude)
lon = float(longitude)
alt = float(altitude)
pres = float(pressure)
temp = float(temperature)
meth = str(solarpos_meth)
valid_methods = ['nrel_numpy', 'nrel_numba', 'pyephem', 'ephemeris', 'nrel_c']
if meth not in valid_methods:
return "Error: solarpos_meth must be one of nrel_numpy, nrel_numba, pyephem, ephemeris, nrel_c"
df = pvlib_get_solarposition(
time=dt_index,
latitude=lat,
longitude=lon,
altitude=alt,
pressure=pres,
method=meth,
temperature=temp
)
result = []
for i in range(len(dt_index)):
az = float(df.iloc[i]["azimuth"])
el = float(df.iloc[i]["elevation"])
zen = float(df.iloc[i]["apparent_zenith"])
result.append([az, el, zen])
return result
except Exception as e:
return f"Error: {str(e)}"