linear interpolation -- make grid
<p>I want to interpolate between different models. To make things easier, my data is shown below:</p>

<p><a href="http://i.stack.imgur.com/8Obef.png" rel="nofollow"><img src="http://i.stack.imgur.com/8Obef.png" alt="enter image description here"></a></p>

<p>I have 10 different simulations (which I will call <code>z</code>). For each <code>z</code> I have an <code>array x</code> and an <code>array y</code> (where for a given <code>z</code>, <code>len(x)=len(y)</code>).
For example: </p>

<p>for <code>z=1</code>: <code>x.shape=(1200,)</code> and <code>y.shape=(1200,)</code></p>

<p>for <code>z=2</code>: <code>x.shape=(1250,)</code> and <code>y.shape=(1250,)</code></p>

<p>for <code>z=3</code>: <code>x.shape=(1236,)</code> and <code>y.shape=(1236,)</code></p>

<p>and so on ...</p>

<p>I want to interpolate so that for a given <code>z</code> and <code>x</code>, I get <code>y</code>. For example, for <code>z=2.5</code> and <code>x=10**9</code>, the code outputs <code>y</code>. I am assuming that:</p>

<p><code>y = a*x + b*z + c</code> where of course I don't know <code>a</code>, <code>b</code>, and <code>c</code>.</p>

<p>My question is that how do I store the data in a grid? I am confused since for a different <code>z</code> the size of <code>x</code> and <code>y</code> differs. How is it possible to build a grid?</p>

<h2>UPDATE</h2>

<p>I was able to partially solve my problem. What I did first is that I interpolated between <code>x</code> and <code>y</code> using <code>interp1d</code>. It worked perfectly fine. I then <em>created</em> a new grid of <code>x</code> and <code>y</code> values. Briefly the method is:</p>

<pre><code>f = interp1d(x, y, kind='linear')
new_x = np.linspace(10**7, 4*10**9, 10000)
new_y = f(new_x)
</code></pre>

<p>I then interpolated <code>x</code>, <code>y</code>, and <code>z</code>:</p>

<pre><code>ff = LinearNDInterpolator( (x, z), y)
</code></pre>

<p>To test whether the method work, here's a plot with <code>z=3</code>.</p>

<p><a href="http://i.stack.imgur.com/Sc6dt.png" rel="nofollow"><img src="http://i.stack.imgur.com/Sc6dt.png" alt="enter image description here"></a></p>

<p>The plot looks good till <code>x=10**8</code>. Indeed, the line deviates from the original model. Here's a plot when I further zoom in:</p>

<p><a href="http://i.stack.imgur.com/utLn9.png" rel="nofollow"><img src="http://i.stack.imgur.com/utLn9.png" alt="enter image description here"></a></p>

<p>The interpolation obviously is not good when <code>x &gt; 10**8</code>. How can I fix it?</p>

<p>It seems that in your problem the curves y(x) are well behaving, so you could probably just interpolate y(x) for the given values of z first and then interpolate between the obtained y-values afterwards.</p>

<pre><code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

import random

#####
# Generate some data
#####
generate = lambda x, z: 1./(x+1.)+(z*x/75.+z/25.)

def f(z):
    #create an array of values between zero and 100 of random length
    x = np.linspace(0,10., num=random.randint(42,145))
    #generate corresponding y values
    y = generate(x, z)
    return np.array([x,y])

Z = [1, 2, 3, 3.6476, 4, 5.1]
A = [f(z) for z in Z]
#now A contains the dataset of [x,y] pairs for each z value

#####
# Interpolation
#####
def do_interpolation(x,z):
    #assume Z being sorted in ascending order
    #look for indizes of z values closest to given z
    ig = np.searchsorted(Z, z)
    il = ig-1
    #interpolate y(x) for those z values
    yg = np.interp(x, A[ig][0,:], A[ig][1,:])
    yl = np.interp(x, A[il][0,:], A[il][1,:])
    #linearly interpolate between yg and yl  
    return yl + (yg-yl)*float(z-Z[il])/(Z[ig] - Z[il])  

# do_interpolation(x,z) will now provide the interpolated data
print do_interpolation( np.linspace(0, 10), 2.5) 

#####
# Plotting, use Slider to change the value of z. 
#####
fig=plt.figure()
fig.subplots_adjust(bottom=0.2)
ax=fig.add_subplot(111)
for i in range(len(Z)):
    ax.plot(A[i][0,:] , A[i][1,:], label="{z}".format(z=Z[i]) )

l, = ax.plot(np.linspace(0, 10) , do_interpolation( np.linspace(0, 10), 2.5), label="{z}".format(z="interpol"), linewidth=2., color="k" )

axn1 = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg='#e4e4e4')
sn1 = Slider(axn1, 'z', Z[0], Z[-1], valinit=2.5)
def update(val):
    l.set_data(np.linspace(0, 10), do_interpolation( np.linspace(0, 10), val))
    plt.draw()
sn1.on_changed(update)

ax.legend()
plt.show()
</code></pre>

python interpolation linear-interpolation