LoginSignup
4
5

More than 3 years have passed since last update.

RegularGridInterpolatorとinterp2dの引数の順番

Last updated at Posted at 2020-09-13

ダサダサの備忘録です。

scipy.interpolate.RegularGridInterpolatorの引数やグリッドの指定の順番でいつも混乱するので、テストコードを書いてみた。
なんで混乱するかというと、scipy.interpolate.interp2dとかと、ぱっと見引数の順番が違うように見えてしまうからである。

いや、interp2dのグリッド用の引数は1次元配列二つで、RegularGridInterpolatorの第1引数は複数次元配列でしょ? モノがちがうじゃん、と言われればそのとおりで、かつ、複数次元配列の場合、x(l個)、y(m個)、z(n個)ならshapeは(n, m, l)じゃん、と言われたら返す言葉もないのだが、、つい、逆に書いてしまうのである。<昔から行列弱い

なので、こうやって恥をさらしておけば、次は間違わないかなー、と祈りつつ備忘録。

import numpy as np
from scipy.interpolate import RegularGridInterpolator

x_iter = np.array([0,1,2,3,4])
y_iter = np.array([5,6,7])
z_iter = np.array([8,9])
print("number of x_iter l = %d" % (len(x_iter)))
print("number of y_iter m = %d" % (len(y_iter)))
print("number of z_iter n = %d" % (len(z_iter)))

def data_func(x, y, z) :
    return x + y*10 + z*100

data = []
for z in z_iter :
    buf2 = []
    for y in y_iter :
        buf = []
        for x in x_iter :
            buf.append(data_func(x, y, z))
        buf2.append(buf)
    data.append(buf2)

data = np.array(data)
print("data", data)
print("shape of data, n x m x l array", data.shape)

data_grid = tuple([z_iter, y_iter, x_iter])
print("data grid with a format tuple(z_iter, y_iter, x_iter) is", data_grid)
f = RegularGridInterpolator(data_grid, data)

point_of_interest = tuple([8.3, 5.5, 1.1])
print("point_of_interest with a format tuple(z, y, x) is", point_of_interest)
interp_value = f(point_of_interest)

print("interpolated value is", interp_value)

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib import colors

figid = 1
plt.figure(figid)
ax1 = plt.subplot(1, 1, 1)
xx, yy = np.meshgrid(x_iter, y_iter)

data_2D = data[0, :, :]
print("shape of data_2D for z_bin = 0", data_2D.shape)
phist = ax1.pcolormesh(xx, yy, data_2D, norm=colors.Normalize())
plt.colorbar(phist)
ax1.set_ylabel("y")
ax1.set_xlabel("x")
plt.savefig("interp_test.png")

forでまわしながらデータを作成する際に、回す順番に注意。
Defaultでは、x,y,zの値に、範囲外の値を指定するとエラーする。この振る舞いはbounds_error引数とfill_value変数でコントロール可能(デフォルトではbounds_error=True, fill_value=nanになっている)

interp_test.png

ちなみに、scipy.interpolation.interp2Dを使う場合はこんな感じ。
Defaultでは、xとyの値に、範囲外の値を指定しても死なない(data table内の一番端の値を返す)。この振る舞いはbounds_error引数とfill_value変数でコントロール可能(デフォルトではbounds_error=False, fill_value=Noneになっている)

import numpy as np
from scipy.interpolate import interp2d

x_iter = np.array([0,1,2,3,4])
y_iter = np.array([5,6,7])
print("number of x_iter l = %d" % (len(x_iter)))
print("number of y_iter m = %d" % (len(y_iter)))

def data_func(x, y) :
    return x + y*10

data = []
for y in y_iter :
    buf = []
    for x in x_iter :
        buf.append(data_func(x, y))
    data.append(buf)

data = np.array(data)
print("data", data)
print("shape of data, m x l array", data.shape)

# order of arguments: x-axis, y-axis, data
f = interp2d(x_iter, y_iter, data)

x = 1.5
y = 5.5
print("datapoint is (%f, %f), data_func(%f, %f) is %f" % (x, y, x, y, data_func(x, y)))
interp_value = f(x, y)
print("interpolated value is", interp_value)

# test2 : what happens if x1 is out of range?
x1 = 7 # x-range is (0, 4)
y1 = 10 # y-range is (5, 7)
print("datapoint is (%f, %f), data_func(%f, %f) is %f" % (x1, y1, x1, y1, data_func(x1, y1)))
interp_value = f(x1, y1)
print("interpolated value is", interp_value)
# this value is 
print("interpolated value for (%f, %f) is %f" % (x_iter[-1], y_iter[-1], f(x_iter[-1], y_iter[-1])))

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib import colors

figid = 1
plt.figure(figid)
ax1 = plt.subplot(1, 1, 1)
xx, yy = np.meshgrid(x_iter, y_iter)

phist = ax1.pcolormesh(xx, yy, data, norm=colors.Normalize())
plt.colorbar(phist)
ax1.set_ylabel("y")
ax1.set_xlabel("x")
plt.savefig("interp_test2D.png")

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5