scipy插值不会平滑我的数据

时间:2015-11-28 15:03:37

标签: python numpy scipy interpolation smoothing

我正试图在scipy中使用插值。这是我的代码:

from Constants import LOWER_LAT, LOWER_LONG, UPPER_LAT, UPPER_LONG, GRID_RESOLUTION

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
from cmath import sin
from scipy.signal.windows import cosine
from scipy import interpolate
from scipy.interpolate import RectBivariateSpline
import numpy
from numpy import meshgrid

#===============================================================
y_range = GRID_RESOLUTION
delta = (UPPER_LAT - LOWER_LAT)/float(GRID_RESOLUTION)
x_range = int((UPPER_LONG - LOWER_LONG)/delta) + 1
x = numpy.linspace(0,x_range-1,x_range)
y = numpy.linspace(0,y_range-1,y_range)
X,Y = meshgrid(x,y)
Z = numpy.zeros((y.size, x.size))
base_val = 0

# fill values for Z
with open('map.txt','rb') as fp:
    for line in fp:
        parts = line[:-1].split("\t")
        tup = parts[0]
        tup = tup[:-1]
        tup = tup[1:]
        yx = tup.strip().replace(" ","").split(",")
        y_val = int(yx[0])
        x_val = int(yx[1])
        h_val = int(parts[-1])

        for i in range(y_range):
            tx = X[i];
            ty = Y[i];
            tz = Z[i];
            for j in range(x_range):
                if (int(tx[j])==x_val) and (int(ty[j])==y_val):
                    tz[j] = h_val + base_val
Z = numpy.array(Z)

# spline = RectBivariateSpline(y, x, Z)
# Z2 = spline(y, x)
f = interpolate.interp2d(x, y, Z,'cubic')
Z2 = f(x,y)


# Plot here
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z2, rstride=1, cstride=1, alpha=0.3, cmap='Accent')
ax.set_xlabel('X')
ax.set_xlim(0, 50)
ax.set_ylabel('Y')
ax.set_ylim(0, 50)
ax.set_zlabel('Z')
# ax.set_zlim(0, 1000)
plt.show()

以上是代码顶部的一些常量:

LOWER_LAT = 32.5098
LOWER_LONG = -84.7485
UPPER_LAT = 47.5617
UPPER_LONG = -69.1699
GRID_RESOLUTION = 50

我的代码创建了1D数组xy,然后使用函数meshgrid创建网格。 Z中的值是从您可以找到here的文本文件中填充的。文本文件中的每一行都具有(y_value,x_value) z_value的格式。 创建网格并插入函数后,我绘制它。但是,我获得的数字与我没有插值的数字相同。具体而言,这两行产生相同的数字:

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.3, cmap='Accent')
ax.plot_surface(X, Y, Z2, rstride=1, cstride=1, alpha=0.3, cmap='Accent')

在上面的行中,Z2的值来自插值函数,Z的值是原始值。 如何进行插值工作? 这是图。 enter image description here

1 个答案:

答案 0 :(得分:2)

我认为您将smoothinginterpolation混为一谈。

在这两种情况下,您都拟合一个能够产生连续近似输入数据的函数。但是,在插值的情况下,插值被约束为准确地通过输入点,而平滑时,这种约束会被放宽。

在上面的示例中,您执行了插值而不是平滑。由于您在与原始数据完全相同的输入点网格上评估插值,因此Z2保证与Z几乎完全相同。进行插值的目的是,您可以在给出不同的x和y值集合(例如,更精细间隔的网格)的情况下评估近似z值。

如果要执行平滑而不是插值,可以尝试将非零值作为s=参数传递给RectBivariateSpline,例如:

spline = RectBivariateSpline(y, x, Z, s=5E7)
Z2 = spline(y, x)

fig, ax = plt.subplots(1, 2, sharex=True, sharey=True,
                       subplot_kw={'projection':'3d'})

ax[0].plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.3, cmap='Accent')
ax[1].plot_surface(X, Y, Z2, rstride=1, cstride=1, alpha=0.3, cmap='Accent')
ax[0].set_title('Original')
ax[1].set_title('Smoothed')

fig.tight_layout()
plt.show()

enter image description here