<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Interpolation with scipy
Step1:  Official documentation
Step2:  Interpolate 1D functions
In the following examples, we interpolate $f(x) \mapsto \sin(x)$
Step3:  Linear interpolation
Step4:  B-Splines interpolation
https
Step5:  Spline linear interpolation
Step6:  Interpolate 2D functions
In the following examples, we interpolate $f(x, y) \mapsto \sin(x) + \sin(y)$
Step7:  Linear interpolation
Documentation
Step8:  Non uniform grid data
Documentation
Step9:  Cubic splines
Step10:  Interpolate unstructured D-dimensional data
Documentation
Step11:  Callable version
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
Explanation: Interpolation with scipy
End of explanation
import numpy as np
import pandas as pd
import scipy.interpolate
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
Explanation: Official documentation: https://docs.scipy.org/doc/scipy/reference/interpolate.html
Import modules and initialize data
End of explanation
xmin, xmax = 0., 4*np.pi
x = np.linspace(xmin, xmax, 10)
y = np.sin(x)
x2 = np.linspace(xmin, xmax, 100)
Explanation: Interpolate 1D functions
In the following examples, we interpolate $f(x) \mapsto \sin(x)$
End of explanation
# Linear interpolation with extrapolation
f = scipy.interpolate.interp1d(x, y,
                               kind='linear',
                               fill_value="extrapolate")
y2 = f(x2)
plt.plot(x, y, "o:b", label="original")
plt.plot(x2, y2, ".-r", label="interpolated")
plt.legend();
Explanation: Linear interpolation
End of explanation
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.splrep.html#scipy.interpolate.splrep
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.splprep.html#scipy.interpolate.splprep
spl = scipy.interpolate.splrep(x, y)
y2 = scipy.interpolate.splev(x2, spl)
plt.plot(x, y, "o:b", label="original")
plt.plot(x2, y2, ".-r", label="interpolated")
plt.legend();
spl = scipy.interpolate.splrep(x, y,
                               xb=x[0], xe=x[-1],   # The interval to fit
                               #s=0.,               # A smoothing factor
                               k=1)                 # The degree fo the spline fit
y2 = scipy.interpolate.splev(x2, spl)
plt.plot(x, y, "o:b", label="original")
plt.plot(x2, y2, ".-r", label="interpolated")
plt.legend();
Explanation: B-Splines interpolation
https://docs.scipy.org/doc/scipy/reference/interpolate.html#d-splines
End of explanation
# Spline linear interpolation with extrapolation (should be the same than spline1...)
f = scipy.interpolate.interp1d(x, y,
                               kind='slinear',
                               fill_value="extrapolate")
y2 = f(x2)
plt.plot(x, y, "o:b", label="original")
plt.plot(x2, y2, ".-r", label="interpolated")
plt.legend();
Explanation: Spline linear interpolation
End of explanation
# Build data
x = np.arange(-1*np.pi, 1*np.pi, np.pi/4)
y = np.arange(-1*np.pi, 1*np.pi, np.pi/4)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx) + np.sin(yy)
# Plot data
fig = plt.figure(figsize=(12, 8))
ax = axes3d.Axes3D(fig)
#ax.plot_wireframe(xx, yy, z)
surf = ax.plot_surface(xx,
                       yy,
                       z,
                       cmap='gnuplot2', # 'jet' # 'gnuplot2'
                       rstride=1,
                       cstride=1,
                       shade=False)
plt.title("Original data")
plt.show();
Explanation: Interpolate 2D functions
In the following examples, we interpolate $f(x, y) \mapsto \sin(x) + \sin(y)$
End of explanation
f = scipy.interpolate.interp2d(x, y, z, kind='linear',
                               bounds_error=True)     # Let 'f' raise an exception when the requested point is outside the range defined by x and y
# Build data
x_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
y_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
xx_hd,yy_hd = np.meshgrid(x_hd, y_hd)
z_hd = np.zeros(xx_hd.shape)
for xi in range(z_hd.shape[0]):
    for yi in range(z_hd.shape[1]):
        z_hd[xi, yi] = f(x_hd[xi], y_hd[yi])
# Plot data
fig = plt.figure(figsize=(12, 8))
ax = axes3d.Axes3D(fig)
surf = ax.plot_surface(xx_hd,
                       yy_hd,
                       z_hd,
                       cmap='gnuplot2', # 'jet' # 'gnuplot2'
                       rstride=1,
                       cstride=1,
                       shade=False)
plt.show();
Explanation: Linear interpolation
Documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html#scipy.interpolate.interp2d
End of explanation
# Build data
x_nu = np.arange(-1*np.pi, 1*np.pi, np.pi/4)
y_nu = np.arange(-1*np.pi, 1*np.pi, np.pi/4)
x_nu = x_nu.tolist()
y_nu = y_nu.tolist()
del x_nu[2]
del y_nu[2]
xx, yy = np.meshgrid(x_nu, y_nu)
z_nu = np.sin(xx) + np.sin(yy)
f = scipy.interpolate.interp2d(x_nu, y_nu, z_nu, kind='linear',
                               bounds_error=True)     # Let 'f' raise an exception when the requested point is outside the range defined by x and y
# Build data
x_nu_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
y_nu_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
xx_nu_hd,yy_nu_hd = np.meshgrid(x_nu_hd, y_nu_hd)
z_nu_hd = np.zeros(xx_nu_hd.shape)
for xi in range(z_nu_hd.shape[0]):
    for yi in range(z_nu_hd.shape[1]):
        z_nu_hd[xi, yi] = f(x_nu_hd[xi], y_nu_hd[yi])
# Plot data
fig = plt.figure(figsize=(12, 8))
ax = axes3d.Axes3D(fig)
surf = ax.plot_surface(xx_nu_hd,
                       yy_nu_hd,
                       z_nu_hd,
                       cmap='gnuplot2', # 'jet' # 'gnuplot2'
                       rstride=1,
                       cstride=1,
                       shade=False)
surf = ax.plot_surface(xx_hd,
                       yy_hd,
                       z_hd,
                       cmap='gnuplot2', # 'jet' # 'gnuplot2'
                       rstride=1,
                       cstride=1,
                       alpha=0.5,
                       shade=False)
plt.show();
Explanation: Non uniform grid data
Documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html#scipy.interpolate.interp2d
End of explanation
f = scipy.interpolate.interp2d(x, y, z, kind='cubic',
                               bounds_error=True)     # Let 'f' raise an exception when the requested point is outside the range defined by x and y
# Build data
x_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
y_hd = np.arange(-1*np.pi, 1*np.pi-np.pi/4, np.pi/32)
xx_hd,yy_hd = np.meshgrid(x_hd, y_hd)
z_hd = np.zeros(xx_hd.shape)
for xi in range(z_hd.shape[0]):
    for yi in range(z_hd.shape[1]):
        z_hd[xi, yi] = f(x_hd[xi], y_hd[yi])
# Plot data
fig = plt.figure(figsize=(12, 8))
ax = axes3d.Axes3D(fig)
surf = ax.plot_surface(xx_hd,
                       yy_hd,
                       z_hd,
                       cmap='gnuplot2', # 'jet' # 'gnuplot2'
                       rstride=1,
                       cstride=1,
                       shade=False)
plt.show();
Explanation: Cubic splines
End of explanation
def func(x, y):
    return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2
grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j]
points = np.random.rand(1000, 2)
values = func(points[:,0], points[:,1])
grid_z0 = scipy.interpolate.griddata(points, values, (grid_x, grid_y), method='nearest')
grid_z1 = scipy.interpolate.griddata(points, values, (grid_x, grid_y), method='linear')
grid_z2 = scipy.interpolate.griddata(points, values, (grid_x, grid_y), method='cubic')
plt.subplot(221)
plt.imshow(func(grid_x, grid_y).T, extent=(0,1,0,1), origin='lower')
plt.plot(points[:,0], points[:,1], 'k.', ms=1)
plt.title('Original')
plt.subplot(222)
plt.imshow(grid_z0.T, extent=(0,1,0,1), origin='lower')
plt.title('Nearest')
plt.subplot(223)
plt.imshow(grid_z1.T, extent=(0,1,0,1), origin='lower')
plt.title('Linear')
plt.subplot(224)
plt.imshow(grid_z2.T, extent=(0,1,0,1), origin='lower')
plt.title('Cubic')
plt.gcf().set_size_inches(6, 6)
plt.tight_layout()
plt.show()
Explanation: Interpolate unstructured D-dimensional data
Documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
Scipy official documentation example
Example taken from https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
End of explanation
class InterpoledGridData:
    
    def __init__(self, x, y, z, interpolation_method='linear', fill_value=float('nan')):
        self.x = x
        self.y = y
        self.z = z
        self.fill_value = fill_value
        self.interpolation_method = interpolation_method
    
    def __call__(self, x1_mesh, x2_mesh):
        z = scipy.interpolate.griddata(points = (self.x, self.y),
                                       values = self.z,
                                       xi = (x1_mesh, x2_mesh),
                                       fill_value=self.fill_value,
                                       method = self.interpolation_method)
        
        if z.ndim == 0:
            z = float(z)
            
        return z
x = np.random.rand(1000)
y = np.random.rand(1000)
z = func(x, y)
f = InterpoledGridData(x, y, z, interpolation_method='cubic')
f(0.5, 0.5)
x_hd = np.linspace(x.min(),
                   x.max(),
                   100)
y_hd = np.linspace(y.min(),
                   y.max(),
                   100)
xx_hd, yy_hd = np.meshgrid(x_hd, y_hd)
z_hd = f(xx_hd, yy_hd)
# Plot data
fig = plt.figure(figsize=(12, 8))
ax = axes3d.Axes3D(fig, azim=150, elev=30)
surf = ax.plot_surface(xx_hd,
                       yy_hd,
                       z_hd,
                       cmap='gnuplot2',
                       rstride=1,
                       cstride=1,
                       vmin=np.nanmin(z_hd),
                       vmax=np.nanmax(z_hd),
                       shade=False)
plt.show();
fig, ax = plt.subplots(figsize=(12, 8))
im = ax.pcolormesh(xx_hd, yy_hd, z_hd,
                   #shading='gouraud',
                   cmap='gnuplot2')
plt.colorbar(im, ax=ax)
plt.show();
Explanation: Callable version
End of explanation
<END_TASK>