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>What you're doing seems a bit weird to me, at least you seem to use a single set of <code>y</code> values to do the interpolation. What I suggest is not performing two interpolations one after the other, but considering your <code>y(z,x)</code> function as the result of a pure 2d interpolation problem.</p>

<p>So as I noted in a comment, I suggest using <code>scipy.interpolate.LinearNDInterpolator</code>, the same object that <code>griddata</code> uses under the hood for bilinear interpolatin. As we've also discussed in comments, you need to have a single interpolator that you can query multiple times afterwards, so we have to use the lower-level interpolator object, as that is callable.</p>

<p>Here's a full example of what I mean, complete with dummy data and plotting:</p>

<pre><code>import numpy as np
import scipy.interpolate as interp
import matplotlib.pyplot as plt

# create dummy data
zlist = range(4)  # z values
# one pair of arrays for each z value in a list:
xlist = [np.linspace(-1,1,41),
         np.linspace(-1,1,61),
         np.linspace(-1,1,55),
         np.linspace(-1,1,51)]
funlist = [lambda x:0.1*np.ones_like(x),
           lambda x:0.2*np.cos(np.pi*x)+0.4,
           lambda x:np.exp(-2*x**2)+0.5,
           lambda x:-0.7*np.abs(x)+1.7]
ylist = [f(x) for f,x in zip(funlist,xlist)]

# create contiguous 1d arrays for interpolation
all_x = np.concatenate(xlist)
all_y = np.concatenate(ylist)
all_z = np.concatenate([np.ones_like(x)*z for x,z in zip(xlist,zlist)])

# create a single linear interpolator object
yfun = interp.LinearNDInterpolator((all_z,all_x),all_y)

# generate three interpolated sets: one with z=2 to reproduce existing data,
# two with z=1.5 and z=2.5 respectively to see what happens
xplot = np.linspace(-1,1,30)
z = 2
y_repro = yfun(z,xplot)
z = 1.5
y_interp1 = yfun(z,xplot)
z = 2.5
y_interp2 = yfun(z,xplot)

# plot the raw data (markers) and the two interpolators (lines)
fig,ax = plt.subplots()
for x,y,z,mark in zip(xlist,ylist,zlist,['s','o','v','&lt;','^','*']):
    ax.plot(x,y,'--',marker=mark,label='z={}'.format(z))
ax.plot(xplot,y_repro,'-',label='z=2 interp')
ax.plot(xplot,y_interp1,'-',label='z=1.5 interp')
ax.plot(xplot,y_interp2,'-',label='z=2.5 interp')
ax.set_xlabel('x')
ax.set_ylabel('y')
# reduce plot size and put legend outside for prettiness, see also http://stackoverflow.com/a/4701285/5067311
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

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

<p><a href="http://i.stack.imgur.com/90BJO.png" rel="nofollow"><img src="http://i.stack.imgur.com/90BJO.png" alt="result"></a></p>

<p>You didn't specify how you series of <code>(x,y)</code> array pairs are stored, I used a list of numpy <code>ndarray</code>s. As you see, I flattened the list of 1d arrays into a single set of 1d arrays: <code>all_x</code>, <code>all_y</code>, <code>all_z</code>. These can be used as scattered <code>y(z,x)</code> data from which you can construct the interpolator object. As you can see in the result, for <code>z=2</code> it reproduces the input points, and for non-integer <code>z</code> it interpolates between the relevant <code>y(x)</code> curves.</p>

<p>This method should be applicable to your dataset. One note, however: you have huge numbers on a logarithmic scale on your <code>x</code> axis. This alone could lead to numeric instabilities. I suggest that you also try performing the interpolation using <code>log(x)</code>, it might behave better (this is just a vague guess).</p>

python interpolation linear-interpolation