Extrapolation is inaccurate, but you can do it using scipy.interpolate.interp1d
by telling it not to give bounds errors (bounds_error=False
) and to fill the values via extrapolation (fill_value="extrapolation"
). In my code, I used a cubic spline fit. Also, make use of numpy functions to generate the x
arrays.
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
plt.close("all")
y = [9.996651009, 10.13327408, 10.27003353, 10.43754263, 10.60523071,
10.71136134, 10.81753489, 10.92299416, 11.02853271, 11.10093835,
11.17349619, 11.16565259, 11.15787539, 11.16191795, 11.16626826,
11.16087842, 11.15561384, 11.16940196, 11.18346164, 11.22434472,
11.26537218, 11.35981126, 11.45427174, 11.6102862, 11.76633923,
11.89058563, 12.01486743, 12.21133227, 12.40782023, 12.55682327,
12.7059072, 12.88910065, 13.07234341, 13.20139753, 13.33048759,
13.46960371, 13.60875466, 13.71956075, 13.83042354, 13.91157425,
13.99277241, 14.08548465, 14.17824161, 14.26091536, 14.34364144,
14.43504833, 14.52651725, 14.59548578, 14.66449439, 14.73751377,
14.81058218, 14.88687742, 14.96322511, 15.038278, 15.11342222,
15.1644832, 15.21556914, 15.31798775, 15.42044285, 15.51000031,
15.59959896, 15.68089263, 15.76229354, 15.86213633, 15.96214484,
16.0269976, 16.0923806, 16.16483146, 16.23762336, 16.24233076,
16.24719576, 16.26116812, 16.27543692, 16.28311024, 16.29128992,
16.23458771, 16.17830522, 16.12636211, 16.07478778]
y = np.array(y)[::-1]
step = 50e9
x = np.arange(192.1e12, 196e12+step, step)
x2 = np.arange(191.325e12, 196.125e12+step, step)
f = interp1d(x, y, kind="cubic", bounds_error=False, fill_value="extrapolate")
fig, ax = plt.subplots()
ax.plot(x, y, ".", label="data")
ax.plot(x2, f(x2), "--", label="fit")
ax.legend()
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.show()

Edit: If you do need a polynomial fit, then make use of np.poly1d
. This returns a function that can be evaluated, unlike polyval
which only returns the values (hence the error you were getting).
import numpy as np
import matplotlib.pyplot as plt
plt.close("all")
y = [9.996651009, 10.13327408, 10.27003353, 10.43754263, 10.60523071,
10.71136134, 10.81753489, 10.92299416, 11.02853271, 11.10093835,
11.17349619, 11.16565259, 11.15787539, 11.16191795, 11.16626826,
11.16087842, 11.15561384, 11.16940196, 11.18346164, 11.22434472,
11.26537218, 11.35981126, 11.45427174, 11.6102862, 11.76633923,
11.89058563, 12.01486743, 12.21133227, 12.40782023, 12.55682327,
12.7059072, 12.88910065, 13.07234341, 13.20139753, 13.33048759,
13.46960371, 13.60875466, 13.71956075, 13.83042354, 13.91157425,
13.99277241, 14.08548465, 14.17824161, 14.26091536, 14.34364144,
14.43504833, 14.52651725, 14.59548578, 14.66449439, 14.73751377,
14.81058218, 14.88687742, 14.96322511, 15.038278, 15.11342222,
15.1644832, 15.21556914, 15.31798775, 15.42044285, 15.51000031,
15.59959896, 15.68089263, 15.76229354, 15.86213633, 15.96214484,
16.0269976, 16.0923806, 16.16483146, 16.23762336, 16.24233076,
16.24719576, 16.26116812, 16.27543692, 16.28311024, 16.29128992,
16.23458771, 16.17830522, 16.12636211, 16.07478778]
y = np.array(y)[::-1]
step = 50e9
x = np.arange(192.1e12, 196e12+step, step)
x2 = np.arange(191.325e12, 196.125e12+step, step)
z = np.polyfit(x, y, 20)
p = np.poly1d(z)
fig, ax = plt.subplots()
ax.plot(x, y, ".", label="data")
ax.plot(x2, p(x2), "--", label="fit")
ax.legend()
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.show()

Edit: Using the more updated np.polynomial.Polynomial
methods, we get a similar result using a 5th-order polynomial fit.
import numpy as np
import matplotlib.pyplot as plt
from numpy.polynomial import Polynomial
plt.close("all")
y = [9.996651009, 10.13327408, 10.27003353, 10.43754263, 10.60523071,
10.71136134, 10.81753489, 10.92299416, 11.02853271, 11.10093835,
11.17349619, 11.16565259, 11.15787539, 11.16191795, 11.16626826,
11.16087842, 11.15561384, 11.16940196, 11.18346164, 11.22434472,
11.26537218, 11.35981126, 11.45427174, 11.6102862, 11.76633923,
11.89058563, 12.01486743, 12.21133227, 12.40782023, 12.55682327,
12.7059072, 12.88910065, 13.07234341, 13.20139753, 13.33048759,
13.46960371, 13.60875466, 13.71956075, 13.83042354, 13.91157425,
13.99277241, 14.08548465, 14.17824161, 14.26091536, 14.34364144,
14.43504833, 14.52651725, 14.59548578, 14.66449439, 14.73751377,
14.81058218, 14.88687742, 14.96322511, 15.038278, 15.11342222,
15.1644832, 15.21556914, 15.31798775, 15.42044285, 15.51000031,
15.59959896, 15.68089263, 15.76229354, 15.86213633, 15.96214484,
16.0269976, 16.0923806, 16.16483146, 16.23762336, 16.24233076,
16.24719576, 16.26116812, 16.27543692, 16.28311024, 16.29128992,
16.23458771, 16.17830522, 16.12636211, 16.07478778]
y = np.array(y)[::-1]
step = 50e9
x = np.arange(192.1e12, 196e12+step, step)
x2 = np.arange(191.325e12, 196.125e12+step, step)
p = Polynomial.fit(x, y, 5)
fig, ax = plt.subplots()
ax.plot(x, y, ".", label="data")
ax.plot(x2, p(x2), "--", label="fit")
ax.legend()
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.show()
