Note
Click here to download the full example code
Misalignment ErrorΒΆ
How much transposition error is caused by small sensor misalignments?
This example simulates how alignment error translates to transposition error.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pvlib
lat, lon = 40, -80
times = pd.date_range('2019-01-01 06:00', '2019-01-01 21:00',
freq='5min', tz='Etc/GMT+5')
dni_extra = pvlib.irradiance.get_extra_radiation(times)
location = pvlib.location.Location(lat, lon)
solpos = location.get_solarposition(times)
clearsky = location.get_clearsky(times, model='ineichen',
solar_position=solpos)
def transpose(surface_tilt, surface_azimuth):
transposed = pvlib.irradiance.get_total_irradiance(
surface_tilt=surface_tilt,
surface_azimuth=surface_azimuth,
solar_zenith=solpos['apparent_zenith'],
solar_azimuth=solpos['azimuth'],
dni=clearsky['dni'],
ghi=clearsky['ghi'],
dhi=clearsky['dhi'],
dni_extra=dni_extra,
albedo=0.15,
model='haydavies',
)
return transposed['poa_global']
true_poa = transpose(20, 180)
true_total = true_poa.resample('h').mean().sum()
df_tilt = pd.DataFrame()
df_azi = pd.DataFrame()
heatmap_results = []
for azimuth_delta in np.linspace(-5, 5, 11)[::-1]:
for tilt_delta in np.linspace(-5, 5, 11)[::-1]:
surface_tilt = 20 + tilt_delta
surface_azimuth = 180 + azimuth_delta
misaligned_poa = transpose(surface_tilt, surface_azimuth)
if tilt_delta == 0:
label = f'{surface_azimuth:0.01f}'
df_azi[label] = misaligned_poa
if azimuth_delta == 0:
label = f'{surface_tilt:0.01f}'
df_tilt[label] = misaligned_poa
misaligned_total = misaligned_poa.resample('h').mean().sum()
heatmap_results.append({
'surface_tilt': surface_tilt,
'surface_azimuth': surface_azimuth,
'max_abs_error': (misaligned_poa - true_poa).abs().max(),
'total_error': (misaligned_total / true_total - 1) * 100
})
def plot_ts(df, case, base):
fig, axes = plt.subplots(2, 1, sharex=True, figsize=(6, 6))
df.plot(ax=axes[0])
axes[0].set_ylabel('Transposed Irradiance [W m^-2]')
axes[0].legend(loc='upper right')
error = (df.divide(df[base], axis=0) - 1) * 100
error.plot(ax=axes[1])
axes[1].set_ylabel('Error [%]')
axes[1].legend(loc='upper right')
fig.tight_layout()
fig.show()
plot_ts(df_tilt, 'Tilt', '20.0')

plot_ts(df_azi, 'Azimuth', '180.0')

df = pd.DataFrame(heatmap_results)
def plot(df, column):
df2 = df.pivot_table(index='surface_azimuth',
columns='surface_tilt',
values=column)
fig = plt.figure()
plt.pcolormesh(df2.columns, df2.index, df2, shading='auto')
plt.colorbar()
plt.ylabel(r'Surface Azimuth [$\degree$]')
plt.xlabel(r'Surface Tilt [$\degree$]')
return fig
fig = plot(df, 'max_abs_error')
fig.suptitle('Max Absolute Error [W m^-2]')
fig.show()
![Max Absolute Error [W m^-2]](../../_images/sphx_glr_misalignment-error_003.png)
fig = plot(df, 'total_error')
fig.suptitle('Total Error [%]')
fig.show()
![Total Error [%]](../../_images/sphx_glr_misalignment-error_004.png)
Total running time of the script: ( 0 minutes 2.452 seconds)