2

I have difficulty to interpolate a matrix/data frame in python.

Suppose we I have a matrix M = 3x4 and x = [1 3 5], y = [0.1 0.4 0.5 0.7]

This is my way to do interpolate and then plot in Matlab.

xq = 1:1:5;
yq = 0.1:0.1:1;
[xq,yq] = meshgrid(xq,yq);
zq = interp2(y,x,M,xq,yq);
figure
h=pcolor(xq,yq,zq)
set(h,'EdgeColor','none')

This is a possible way in Python

from scipy import interpolate
import numpy as np

def my_interp(X, Y, Z, x, y, spn=3):
    xs,ys = map(np.array,(x,y))
    z = np.zeros(xs.shape)
    for i,(x,y) in enumerate(zip(xs,ys)):
        # get the indices of the nearest x,y
        xi = np.argmin(np.abs(X[0,:]-x))
        yi = np.argmin(np.abs(Y[:,0]-y))
        xlo = max(xi-spn, 0)
        ylo = max(yi-spn, 0)
        xhi = min(xi+spn, X[0,:].size)
        yhi = min(yi+spn, Y[:,0].size)
        # make slices of X,Y,Z that are only a few items wide
        nX = X[xlo:xhi, ylo:yhi]
        nY = Y[xlo:xhi, ylo:yhi]
        nZ = Z[xlo:xhi, ylo:yhi]
        intp = interpolate.interp2d(nX, nY, nZ)
        z[i] = intp(x,y)[0]
    return z

zq = my_interp(y, x, M, xq, yq)
emax
  • 6,965
  • 19
  • 74
  • 141
  • 1
    Some blatant self-promotion: [interpolation (look for griddata)](http://stackoverflow.com/questions/34643642/scipy-interp2d-bisplrep-unexpected-output-when-given-1d-input/34656728#34656728) and [pcolor(mesh)](http://stackoverflow.com/questions/35162798/superimpose-heat-maps-in-one-plot-in-python/35166749#35166749). The necessary functions are well documented. – Andras Deak -- Слава Україні Mar 04 '16 at 22:12
  • You might describe the process and outcome for those Python folks who aren't conversant with MATLAB functionality. – Prune Mar 04 '16 at 22:17
  • Thanks guys...:) I will share my Python code! – emax Mar 04 '16 at 22:35
  • @Prune actually, prepending `np.` `sp.interpolate.` or `plt.` will make this almost 1:1 with numpy. As in `np.meshgrid`, `sp.interpolate.griddata`, `plt.pcolor`. Even `sp.interpolate.interp2d` would work, but it's best avoiding it. Otherwise I fully support your notion, needs more info for general clarity. – Andras Deak -- Слава Україні Mar 04 '16 at 22:46
  • numpy's `np.interp2d` is the equivalent command – roadrunner66 Mar 04 '16 at 22:59
  • @roadrunner66 numpy doesn't have one in 1.10.1 at least. – Andras Deak -- Слава Україні Mar 04 '16 at 23:04
  • 1
    @Andras -- I quite agree; this is why I didn't downvote or vote to close. It's clear to *me*, but the original post excludes some potential contributions. – Prune Mar 04 '16 at 23:05

1 Answers1

3

As I noted in a comment, your code is 1:1 translatable to python using the necessary libraries. You need numpy for linspace/meshgrid, matplotlib.pyplot for pcolor(mesh), scipy.interpolate for griddata. I was going to say "interp2d is available but don't use it, but it turns out that you need extrapolation outside the convex hull of your input data, so griddata won't cut it. Here's a solution with interp2d, but take the results with a grain of salt:

import numpy as np
import scipy.interpolate as interp
import matplotlib.pyplot as plt

# input
xv = np.array([1, 3, 5])
yv = np.array([0.1, 0.4, 0.5, 0.7])
x,y = np.meshgrid(xv,yv)
M = np.random.rand(4,3)

xqv = np.arange(1,6)
yqv = np.arange(0.1,1.1,0.1)
xq,yq = np.meshgrid(xqv,yqv)
zqfun = interp.interp2d(x,y,M)
zq = zqfun(xqv,yqv)

plt.figure()
#h = plt.pcolor(xq,yq,zq)
h = plt.pcolormesh(xq,yq,zq)   # <-- same thing but faster

Result(left) compared with your MATLAB original (right; after fixing the order x,y,M in interp2d):

result matlab original

You can see that the results differ at the sides, this is because MATLAB always throws away the last row and column of the data, while matplotlib doesn't.

Community
  • 1
  • 1