VASUDEVAN
VASUDEVAN

Reputation: 101

2 dimensional interpolation problem

I have DATA on x and y axes and the output is on z

for example

y = 10
x = [1,2,3,4,5,6]
z = [2.3,3.4,5.6,7.8,9.6,11.2]

y = 20 
x = [1,2,3,4,5,6]
z = [4.3,5.4,7.6,9.8,11.6,13.2]

y = 30 
x = [1,2,3,4,5,6]
z = [6.3,7.4,8.6,10.8,13.6,15.2]

how can i find the value of z when y = 15 x = 3.5

I was trying to use scipy but i am very new at it

Thanks a lot for the help

vibhor

Upvotes: 1

Views: 7020

Answers (3)

Luka Rahne
Luka Rahne

Reputation: 10447

scipy.interpolate.bisplrep

Reference: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html

import scipy
import math
import numpy
from scipy import interpolate


x= [1,2,3,4,5,6]
y= [10,20,30]

Y = numpy.array([[i]*len(x) for i in y])
X = numpy.array([x for i in y])
Z = numpy.array([[2.3,3.4,5.6,7.8,9.6,11.2],
                 [4.3,5.4,7.6,9.8,11.6,13.2],
                 [6.3,7.4,8.6,10.8,13.6,15.2]]) 

tck = interpolate.bisplrep(X,Y,Z)
print interpolate.bisplev(3.5,15,tck) 


7.84921875

Upper solution does not give you perfect fit. check

print interpolate.bisplev(x,y,tck)

[[  2.2531746    4.2531746    6.39603175]
 [  3.54126984   5.54126984   7.11269841]
 [  5.5031746    7.5031746    8.78888889]
 [  7.71111111   9.71111111  10.9968254 ]
 [  9.73730159  11.73730159  13.30873016]
 [ 11.15396825  13.15396825  15.2968254 ]]

to overcome this interpolate whit polyinomials of 5rd degree in x and 2nd degree in y direction

tck = interpolate.bisplrep(X,Y,Z,kx=5,ky=2)
print interpolate.bisplev(x,y,tck) 

[[  2.3   4.3   6.3]
 [  3.4   5.4   7.4]
 [  5.6   7.6   8.6]
 [  7.8   9.8  10.8]
 [  9.6  11.6  13.6]
 [ 11.2  13.2  15.2]]

This yield

print interpolate.bisplev(3.5,15,tck)

7.88671875

Plotting:
reference http://matplotlib.sourceforge.net/examples/mplot3d/surface3d_demo.html

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z,rstride=1, cstride=1, cmap=cm.jet)
plt.show()

Upvotes: 5

Alex Martelli
Alex Martelli

Reputation: 881477

Given (not as Python code, since the second assignment would obliterate the first in each case, of course;-):

y = 10
x = [1,2,3,4,5,6]
z = [2.3,3.4,5.6,7.8,9.6,11.2]

y = 20 
x = [1,2,3,4,5,6]
z = [4.3,5.4,7.6,9.8,11.6,13.2]

you ask: "how can i find the value of z when y = 15 x = 3.5"?

Since you're looking at a point exactly equidistant in both x and y from the given "grid", you just take the midpoint between the grid values (if you had values not equidistant, you'd take a proportional midpoint, see later). So for y=10, the z values for x 3 and 4 are 5.6 and 7.8, so for x 3.5 you estimate their midpoint, 6.7; and similarly for y=20 you estimate the midpoint between 7.6 and 9.8, i.e., 8.7. Finally, since you have y=15, the midpoint between 6.7 and 8.7 is your final interpolated value for z: 7.7.

Say you had y=13 and x=3.8 instead. Then for x you'd take the values 80% of the way, i.e.:

  • for y=10, 0.2*5.6+0.8*7.8 -> 7.36

  • for y=20, 0.2*7.6+0.8*9.8 -> 9.46

Now you want the z 30% of the way between these, 0.3*7.36 + 0.7*9.46 -> 8.83, that's z.

This is linear interpolation, and it's really very simple. Do you want to compute it by hand, or find routines that do it for you (given e.g. numpy arrays as "the grids")? Even in the latter case, I hope this "manual" explanation (showing what you're doing in the most elementary of arithmetical terms) can help you understand what you're doing...;-).

There are more advanced forms of interpolation, of course -- do you need those, or does linear interpolation suffice for your use case?

Upvotes: 1

malonso
malonso

Reputation: 2295

I would say just take the average of the values around it. So if you need X=3.5 and Y=15 (3.5,15), you average (3,10), (3,20), (4,10) and (4,20). Since I have no idea what the data is you are dealing with, I am not sure if the exact proximity would matter - in which case you can just stick w/the average - or if you need to do some sort of inverse distance weighting.

Upvotes: 0

Related Questions