Skip to content

Commit 8773810

Browse files
committed
Replace interp1d #2394
1 parent 57886ce commit 8773810

4 files changed

Lines changed: 66 additions & 19 deletions

File tree

docs/examples/shading/plot_partial_module_shading_simple.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
from pvlib import pvsystem, singlediode
3939
import pandas as pd
4040
import numpy as np
41-
from scipy.interpolate import interp1d
41+
from scipy.interpolate import make_interp_spline
4242
import matplotlib.pyplot as plt
4343

4444
from scipy.constants import e as qe, k as kB
@@ -178,9 +178,9 @@ def plot_curves(dfs, labels, title):
178178

179179

180180
def interpolate(df, i):
181-
"""convenience wrapper around scipy.interpolate.interp1d"""
182-
f_interp = interp1d(np.flipud(df['i']), np.flipud(df['v']), kind='linear',
183-
fill_value='extrapolate')
181+
"""convenience wrapper around scipy.interpolate"""
182+
f_interp = make_interp_spline(np.flipud(df['i']), np.flipud(df['v']), k=1)
183+
184184
return f_interp(i)
185185

186186

pvlib/iam.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ def interp(aoi, theta_ref, iam_ref, method='linear', normalize=True):
440440
method : str, default 'linear'
441441
Specifies the interpolation method.
442442
Useful options are: 'linear', 'quadratic', 'cubic'.
443-
See scipy.interpolate.interp1d for more options.
443+
See scipy.interpolate for more options.
444444
445445
normalize : boolean, default True
446446
When true, the interpolated values are divided by the interpolated
@@ -470,7 +470,7 @@ def interp(aoi, theta_ref, iam_ref, method='linear', normalize=True):
470470
'''
471471
# Contributed by Anton Driesse (@adriesse), PV Performance Labs. July, 2019
472472

473-
from scipy.interpolate import interp1d
473+
from scipy.interpolate import CubicSpline, make_interp_spline
474474

475475
# Scipy doesn't give the clearest feedback, so check number of points here.
476476
MIN_REF_VALS = {'linear': 2, 'quadratic': 3, 'cubic': 4, 1: 2, 2: 3, 3: 4}
@@ -483,10 +483,31 @@ def interp(aoi, theta_ref, iam_ref, method='linear', normalize=True):
483483
raise ValueError("Negative value(s) found in 'iam_ref'. "
484484
"This is not physically possible.")
485485

486-
interpolator = interp1d(theta_ref, iam_ref, kind=method,
487-
fill_value='extrapolate')
488-
aoi_input = aoi
486+
theta_ref = np.asarray(theta_ref)
487+
iam_ref = np.asarray(iam_ref)
488+
489+
if method == "linear":
490+
spline = make_interp_spline(theta_ref, iam_ref, k=1)
491+
492+
def interpolator(x):
493+
return spline(x)
494+
495+
elif method == "quadratic":
496+
spline = make_interp_spline(theta_ref, iam_ref, k=2)
497+
498+
def interpolator(x):
499+
return spline(x)
489500

501+
elif method == "cubic":
502+
spline = CubicSpline(theta_ref, iam_ref, extrapolate=True)
503+
504+
def interpolator(x):
505+
return spline(x)
506+
507+
else:
508+
raise ValueError(f"Invalid interpolation method '{method}'.")
509+
510+
aoi_input = aoi
490511
aoi = np.asanyarray(aoi)
491512
aoi = np.abs(aoi)
492513
iam = interpolator(aoi)

pvlib/spectrum/response.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import numpy as np
77
import pandas as pd
88
import scipy.constants
9-
from scipy.interpolate import interp1d
9+
from scipy.interpolate import CubicSpline
1010

1111

1212
_PLANCK_BY_LIGHT_SPEED_OVER_ELEMENTAL_CHARGE_BY_BILLION = (
@@ -66,16 +66,16 @@ def get_example_spectral_response(wavelength=None):
6666
if wavelength is None:
6767
resolution = 5.0
6868
wavelength = np.arange(280, 1200 + resolution, resolution)
69+
x = SR_DATA[0]
70+
y = SR_DATA[1]
71+
spline = CubicSpline(
72+
x, y,
73+
extrapolate=False
74+
)
75+
values = spline(wavelength)
76+
values[(wavelength < x[0]) | (wavelength > x[-1])] = 0.0
6977

70-
interpolator = interp1d(SR_DATA[0], SR_DATA[1],
71-
kind='cubic',
72-
bounds_error=False,
73-
fill_value=0.0,
74-
copy=False,
75-
assume_sorted=True)
76-
77-
sr = pd.Series(data=interpolator(wavelength), index=wavelength)
78-
78+
sr = pd.Series(data=values, index=wavelength)
7979
sr.index.name = 'wavelength'
8080
sr.name = 'spectral_response'
8181

tests/test_iam.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,32 @@ def test_iam_interp():
213213
with pytest.raises(ValueError):
214214
_iam.interp(0.0, [0, 90], [1, -1])
215215

216+
# check linear after updating interp1d
217+
theta_ref = np.array([0, 60, 90])
218+
iam_ref = np.array([1.0, 0.8, 0.0])
219+
220+
aoi = np.array([0, 30, 60])
221+
iam = _iam.interp(
222+
aoi, theta_ref, iam_ref,
223+
method="linear", normalize=False)
224+
expected = np.array([1.0, 0.9, 0.8])
225+
np.testing.assert_allclose(iam, expected)
226+
227+
# check quadratic
228+
theta_ref = np.array([0, 30, 60, 90])
229+
iam_ref = 1.0 - 1e-4 * theta_ref**2
230+
aoi = np.array([15, 45, 75])
231+
iam = _iam.interp(
232+
aoi,
233+
theta_ref,
234+
iam_ref,
235+
method="quadratic",
236+
normalize=False
237+
)
238+
239+
expected = 1.0 - 1e-4 * aoi**2
240+
np.testing.assert_allclose(iam, expected, rtol=1e-12)
241+
216242

217243
@pytest.mark.parametrize('aoi,expected', [
218244
(45, 0.9975036250000002),

0 commit comments

Comments
 (0)