SOLARPOSITION
Overview
The SOLARPOSITION
function calculates the solar azimuth, elevation, and apparent zenith angles for given times and locations using the NREL SPA algorithm via the pvlib
Python package. This is essential for photovoltaic system modeling, solar resource assessment, and solar tracking applications. The function leverages the pvlib.solarposition.get_solarposition
method, which is widely used in the solar energy industry for accurate solar position calculations. For more details, see the pvlib solarposition documentation .
This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=SOLARPOSITION(time, latitude, longitude, [altitude], [pressure], [method], [temperature])
time
(str or 2D list of str, required): A single ISO8601 datetime string (e.g.,2024-06-20T12:00:00Z
) or a table of such strings (each row is a single string).latitude
(float, required): Latitude in decimal degrees. Positive north of equator, negative south.longitude
(float, required): Longitude in decimal degrees. Positive east of prime meridian, negative west.altitude
(float, optional, default=0.0): Altitude above sea level in meters.pressure
(float, optional, default=101325.0): Atmospheric pressure in Pascals.method
(str, optional, default=‘nrel_numpy’): Calculation method. Options: ‘nrel_numpy’, ‘nrel_numba’, ‘pyephem’, ‘ephemeris’, ‘nrel_c’.temperature
(float, optional, default=12.0): Air temperature in degrees Celsius.
The function returns a 2D list with columns: Azimuth (deg), Elevation (deg), Apparent Zenith (deg), or a 2D list of error messages if input is invalid.
Examples
Example 1: Single Time, Default Options
In Excel:
=SOLARPOSITION("2024-06-20T12:00:00Z", 35.0, -120.0)
Expected output:
Azimuth | Elevation | Apparent Zenith |
---|---|---|
180.0 | 72.0 | 18.0 |
Example 2: Multiple Times
In Excel:
=SOLARPOSITION({"2024-06-20T06:00:00Z";"2024-06-20T12:00:00Z"}, 35.0, -120.0)
Expected output:
Azimuth | Elevation | Apparent Zenith |
---|---|---|
60.0 | 10.0 | 80.0 |
180.0 | 72.0 | 18.0 |
Example 3: Custom Altitude and Pressure
In Excel:
=SOLARPOSITION("2024-12-21T12:00:00Z", 35.0, -120.0, 100.0, 90000.0)
Expected output:
Azimuth | Elevation | Apparent Zenith |
---|---|---|
180.0 | 30.0 | 60.0 |
Example 4: Custom Method and Temperature
In Excel:
=SOLARPOSITION("2024-06-20T12:00:00Z", 35.0, -120.0, 0.0, 101325.0, "nrel_numpy", 25.0)
Expected output:
Azimuth | Elevation | Apparent Zenith |
---|---|---|
180.0 | 72.0 | 18.0 |
This means, for example, at noon on June 20, 2024, at latitude 35°N and longitude 120°W, the sun’s azimuth is approximately 180°, elevation is 72°, and apparent zenith is 18°.
Python Code
import micropip
await micropip.install('pvlib')
import pandas as pd
from pvlib.solarposition import get_solarposition as pvlib_get_solarposition
def solarposition(time, latitude, longitude, altitude=0.0, pressure=101325.0, method='nrel_numpy', temperature=12.0):
"""
Calculate solar azimuth, elevation, and apparent zenith for given times and location.
Args:
time: A single ISO8601 datetime string or a 2D list of ISO8601 datetime strings (each row is a single string).
latitude: Latitude in decimal degrees.
longitude: Longitude in decimal degrees.
altitude: Altitude above sea level in meters (default: 0.0).
pressure: Atmospheric pressure in Pascals (default: 101325.0).
method: Calculation method (default: 'nrel_numpy').
temperature: Air temperature in degrees Celsius (default: 12.0).
Returns:
2D list: Each row is [azimuth, elevation, apparent_zenith] (floats), or a 2D list of error messages if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Accept a single string for time or a 2D list of strings only
if isinstance(time, str):
time = [[time]]
if not (isinstance(time, list) and all(isinstance(row, list) and len(row) == 1 and isinstance(row[0], str) for row in time)):
return [["Invalid input: time must be a single string or a 2D list of single string rows."]]
try:
times = [row[0] for row in time]
dt_index = pd.DatetimeIndex(times)
except Exception:
return [["Invalid input: time values must be ISO8601 datetime strings."]]
try:
lat = float(latitude)
lon = float(longitude)
alt = float(altitude)
pres = float(pressure)
temp = float(temperature)
meth = str(method)
except Exception:
return [["Invalid input: latitude, longitude, altitude, pressure, temperature must be numbers."]]
try:
df = pvlib_get_solarposition(
time=dt_index,
latitude=lat,
longitude=lon,
altitude=alt,
pressure=pres,
method=meth,
temperature=temp
)
# Extract azimuth, elevation, apparent_zenith
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([round(az, 1), round(el, 1), round(zen, 1)])
return result
except Exception as e:
return [[f"pvlib error: {e}"]]
Live Notebook
Edit this function in a live notebook .