SHADED_FRACTION1D
This function computes the beam-shading fraction for row-based PV systems (both fixed-tilt and single-axis trackers).
It models row-to-row shading based on collector geometry, sun angles, and row orientation. It supports terrain slope perpendicular to the rows (cross-axis slope) and torque tube offsets. A value of 1 indicates complete shading, while 0 indicates no shading.
Excel Usage
=SHADED_FRACTION1D(solar_zenith, solar_azimuth, axis_azimuth, shaded_row_rotation, collector_width, pitch, axis_tilt, surface_to_axis_offset, cross_axis_slope)
solar_zenith(list[list], required): Sun’s apparent zenith angle (degrees).solar_azimuth(list[list], required): Sun’s azimuth angle (degrees).axis_azimuth(float, required): Direction of the row axes (degrees).shaded_row_rotation(list[list], required): Rotation angle of the receiving row (degrees).collector_width(float, required): Width (vertical length) of the tilted row.pitch(float, required): Axis-to-axis spacing between rows.axis_tilt(float, optional, default: 0): Tilt of the row axis from horizontal (degrees).surface_to_axis_offset(float, optional, default: 0): Distance between the rotation axis and the collector surface.cross_axis_slope(float, optional, default: 0): Terrain slope perpendicular to the rows (degrees).
Returns (list[list]): 2D list of shaded fractions (0 to 1), or an error string.
Example 1: Shaded fraction in high zenith morning condition
Inputs:
| solar_zenith | solar_azimuth | axis_azimuth | shaded_row_rotation | collector_width | pitch | axis_tilt | surface_to_axis_offset | cross_axis_slope |
|---|---|---|---|---|---|---|---|---|
| 80 | 135 | 90 | 30 | 2 | 3 | 0 | 0.05 | 0 |
Excel formula:
=SHADED_FRACTION1D({80}, {135}, 90, {30}, 2, 3, 0, 0.05, 0)
Expected output:
0.477557
Example 2: Lower zenith reduces shading fraction
Inputs:
| solar_zenith | solar_azimuth | axis_azimuth | shaded_row_rotation | collector_width | pitch | axis_tilt | surface_to_axis_offset | cross_axis_slope |
|---|---|---|---|---|---|---|---|---|
| 50 | 135 | 90 | 30 | 2 | 3 | 0 | 0.05 | 0 |
Excel formula:
=SHADED_FRACTION1D({50}, {135}, 90, {30}, 2, 3, 0, 0.05, 0)
Expected output:
0
Example 3: Vectorized shading fraction for two times
Inputs:
| solar_zenith | solar_azimuth | axis_azimuth | shaded_row_rotation | collector_width | pitch | axis_tilt | surface_to_axis_offset | cross_axis_slope | |||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 80 | 70 | 135 | 145 | 90 | 30 | 30 | 2 | 3 | 0 | 0.05 | 0 |
Excel formula:
=SHADED_FRACTION1D({80,70}, {135,145}, 90, {30,30}, 2, 3, 0, 0.05, 0)
Expected output:
| Result |
|---|
| 0.477557 |
| 0.246733 |
Example 4: Shaded fraction with cross-axis slope
Inputs:
| solar_zenith | solar_azimuth | axis_azimuth | shaded_row_rotation | collector_width | pitch | axis_tilt | surface_to_axis_offset | cross_axis_slope |
|---|---|---|---|---|---|---|---|---|
| 80 | 90 | 180 | -30 | 1.4 | 3 | 0 | 0.1 | 7 |
Excel formula:
=SHADED_FRACTION1D({80}, {90}, 180, {-30}, 1.4, 3, 0, 0.1, 7)
Expected output:
0.824218
Python Code
Show Code
import pandas as pd
import numpy as np
from pvlib.shading import shaded_fraction1d as result_func
def shaded_fraction1d(solar_zenith, solar_azimuth, axis_azimuth, shaded_row_rotation, collector_width, pitch, axis_tilt=0, surface_to_axis_offset=0, cross_axis_slope=0):
"""
Calculate the fraction of a collector width shaded by an adjacent row.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.shading.shaded_fraction1d.html
This example function is provided as-is without any representation of accuracy.
Args:
solar_zenith (list[list]): Sun's apparent zenith angle (degrees).
solar_azimuth (list[list]): Sun's azimuth angle (degrees).
axis_azimuth (float): Direction of the row axes (degrees).
shaded_row_rotation (list[list]): Rotation angle of the receiving row (degrees).
collector_width (float): Width (vertical length) of the tilted row.
pitch (float): Axis-to-axis spacing between rows.
axis_tilt (float, optional): Tilt of the row axis from horizontal (degrees). Default is 0.
surface_to_axis_offset (float, optional): Distance between the rotation axis and the collector surface. Default is 0.
cross_axis_slope (float, optional): Terrain slope perpendicular to the rows (degrees). Default is 0.
Returns:
list[list]: 2D list of shaded fractions (0 to 1), or an error string.
"""
try:
def flatten_num(data):
if not isinstance(data, list): return [float(data)]
flat = []
for row in data:
row = row if isinstance(row, list) else [row]
for val in row:
if val == "": flat.append(float('nan'))
else: flat.append(float(val))
return flat
z_list = flatten_num(solar_zenith)
az_list = flatten_num(solar_azimuth)
rot_list = flatten_num(shaded_row_rotation)
n = len(z_list)
if n == 0 or len(az_list) != n or len(rot_list) != n:
return "Error: All input arrays must have the same non-zero length"
aa = float(axis_azimuth)
cw = float(collector_width)
pi = float(pitch)
at = float(axis_tilt) if axis_tilt is not None else 0.0
off = float(surface_to_axis_offset) if surface_to_axis_offset is not None else 0.0
cas = float(cross_axis_slope) if cross_axis_slope is not None else 0.0
res = result_func(
solar_zenith=np.array(z_list),
solar_azimuth=np.array(az_list),
axis_azimuth=aa,
shaded_row_rotation=np.array(rot_list),
collector_width=cw,
pitch=pi,
axis_tilt=at,
surface_to_axis_offset=off,
cross_axis_slope=cas
)
return [[float(v) if not pd.isna(v) else ""] for v in res]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Sun's apparent zenith angle (degrees).
Sun's azimuth angle (degrees).
Direction of the row axes (degrees).
Rotation angle of the receiving row (degrees).
Width (vertical length) of the tilted row.
Axis-to-axis spacing between rows.
Tilt of the row axis from horizontal (degrees).
Distance between the rotation axis and the collector surface.
Terrain slope perpendicular to the rows (degrees).