Python 二维线性插值:数据和插值点

Python 二维线性插值:数据和插值点,python,numpy,matplotlib,linear-interpolation,mplot3d,Python,Numpy,Matplotlib,Linear Interpolation,Mplot3d,考虑这个y(x)函数: 我们可以在文件中生成这些分散的点:dataset\u 1D.dat: # x y 0 0 1 1 2 0 3 -9 4 -32 以下是这些点的1D插值代码: 加载这个分散的点 创建x_网格 执行一维插值 代码: 该图绘制了以下内容: 现在,考虑这个z(x,y)函数: 我们可以在文件中生成这些分散的点:dataset\u 2D.dat: # x y z 0 0 0 1 1 0 2 2 -4 3 3

考虑这个y(x)函数:

我们可以在文件中生成这些分散的点:
dataset\u 1D.dat

# x   y   
0   0
1   1
2   0
3   -9
4   -32
以下是这些点的1D插值代码:

  • 加载这个分散的点

  • 创建
    x_网格

  • 执行一维插值

  • 代码:

    该图绘制了以下内容:

    现在,考虑这个z(x,y)函数:

    我们可以在文件中生成这些分散的点:
    dataset\u 2D.dat

    # x    y    z
    0   0   0
    1   1   0
    2   2   -4
    3   3   -18
    4   4   -48
    
    在这种情况下,我们必须执行2D插值:

    import numpy as np
    from scipy.interpolate import interp1d, interp2d, interpnd
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    # Load the data:
    x, y, z  = np.loadtxt('./dataset_2D.dat', skiprows = 1).T
    
    # Create the function Z_inter for interpolation:
    Z_inter = interp2d(x, y, z)
    
    # Create the x_mesh and y_mesh :
    x_mesh = np.linspace(1.0, 4, num=10)
    y_mesh = np.linspace(1.0, 4, num=10)
    print x_mesh
    print y_mesh
    
    # We calculate the z-interpolated of this x_mesh and y_mesh :
    Z_interpolated = Z_inter(x_mesh, y_mesh)
    print Z_interpolated
    print type(Z_interpolated)
    print Z_interpolated.shape
    
    # plot: 
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x, y, z, c='r', marker='o')
    plt.legend(['data'], loc='lower left',  prop={'size':12})
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    
    plt.show()
    
    该图绘制了以下内容:

    其中散乱数据再次以红点显示,以与2D图一致

  • 我不知道如何解释
    Z_插值的结果:

    根据上述代码的打印行,
    Z_插值
    是一个n维numpy数组,形状为(10,10)。换句话说,一个包含10行10列的二维矩阵

  • 对于
    x_网格[I]
    y_网格[I]
    的每一个值,我都希望有一个插值的
    z[I]
    值,为什么我没有收到这个

  • 如何在3D绘图中也绘制插值数据(就像2D绘图中的黑色十字)

  • 解释
    Z_插值
    :您的一维
    x_网格
    y_网格
    定义了一个。因此,二维插值返回值
    z
    是一个二维数组,其形状(len(y),len(x))与
    np.meshgrid(x_网格,y_网格)
    匹配。如您所见,您的z[i,i]而不是z[i]是
    x_网格[i]
    y_网格[i]
    的预期值。它只是在网格上有更多的值

    显示所有插值数据的潜在图:

    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.interpolate import interp2d
    
    # Your original function
    x = y = np.arange(0, 5, 0.1)
    xx, yy = np.meshgrid(x, y)
    zz = 2 * (xx ** 2) - (xx ** 3) - (yy ** 2)
    
    # Your scattered points
    x = y = np.arange(0, 5)
    z = [0, 0, -4, -18, -48]
    
    # Your interpolation
    Z_inter = interp2d(x, y, z)
    x_mesh = y_mesh = np.linspace(1.0, 4, num=10)
    Z_interpolated = Z_inter(x_mesh, y_mesh)
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    # Plot your original function
    ax.plot_surface(xx, yy, zz, color='b', alpha=0.5)
    # Plot your initial scattered points
    ax.scatter(x, y, z, color='r', marker='o')
    # Plot your interpolation data
    X_real_mesh, Y_real_mesh = np.meshgrid(x_mesh, y_mesh)
    ax.scatter(X_real_mesh, Y_real_mesh, Z_interpolated, color='g', marker='^')
    plt.show()
    

    需要两个插值步骤。第一个在y数据之间插值。第二个在z数据之间插值。然后使用两个插值阵列绘制
    x_网格

    x_mesh = np.linspace(0, 4, num=16)
    
    yinterp = np.interp(x_mesh, x, y)
    zinterp = np.interp(x_mesh, x, z)
    
    ax.scatter(x_mesh, yinterp, zinterp, c='k', marker='s')
    
    在下面的完整示例中,我还添加了一些y方向的变化,以使解决方案更加通用

    u = u"""# x    y    z
    0   0   0
    1   3   0
    2   9   -4
    3   16   -18
    4   32   -48"""
    
    import io
    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    # Load the data:
    x, y, z  = np.loadtxt(io.StringIO(u), skiprows = 1, unpack=True)
    
    x_mesh = np.linspace(0, 4, num=16)
    
    yinterp = np.interp(x_mesh, x, y)
    zinterp = np.interp(x_mesh, x, z)
    
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x_mesh, yinterp, zinterp, c='k', marker='s')
    ax.scatter(x, y, z, c='r', marker='o')
    plt.legend(['data'], loc='lower left',  prop={'size':12})
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    
    plt.show()
    

    使用
    scipy.interpolate.interp1d
    时,解决方案基本相同:

    u = u"""# x    y    z
    0   0   0
    1   3   0
    2   9   -4
    3   16   -18
    4   32   -48"""
    
    import io
    import numpy as np
    from scipy.interpolate import interp1d
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    # Load the data:
    x, y, z  = np.loadtxt(io.StringIO(u), skiprows = 1, unpack=True)
    
    x_mesh = np.linspace(0, 4, num=16)
    
    fy = interp1d(x, y, kind='cubic')
    fz = interp1d(x, z, kind='cubic')
    
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x_mesh, fy(x_mesh), fz(x_mesh), c='k', marker='s')
    ax.scatter(x, y, z, c='r', marker='o')
    plt.legend(['data'], loc='lower left',  prop={'size':12})
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    
    plt.show()
    

    非常感谢你的回答。不幸的是,
    np.interp
    只允许线性插值。这就是为什么我要使用
    scipy
    interp1d
    ,以便更好地适应
    z(x,y)
    ,它在
    x
    中是立方的。根据您的指示,并将其转换为
    interp1d
    ,我们将:1)在y数据之间插值:
    y_inter=interp1d(x,y,kind='cubic')
    和2)在z数据之间插值:
    z_inter=interp1d(x,z,kind='cubic')
    。然后,我们可以做
    Z_interpolated=Z_inter(x_mesh,y_mesh)
    (我的帖子),但这并没有给出正确的答案。。。我们如何才能做到这一点?谢谢谢谢,我正在深入研究这个问题非常感谢你的回答。在我的帖子中,我使用了
    interp2d
    ,以便使用更好的三次插值。通过在代码中实现这一点,
    Z_inter=interp2d(x,y,Z,kind='cubic')
    它不起作用,你知道为什么吗?感谢您在我的示例代码中仅更改行
    Z_inter=interp2d(x,y,Z)
    将无法工作。根据的“注释”,“沿插值轴所需的最小数据点数量为(k+1)**2,线性插值为k=1,立方插值为k=3,五次插值为k=5”。为了让它工作,将
    x
    y
    更改为
    x=y=np.arange(0,20)
    ,并将
    z
    更改为
    z=2*(x**2)-(x**3)-(y**2)
    。如果这不是原因,请让我知道你有什么错误。
    u = u"""# x    y    z
    0   0   0
    1   3   0
    2   9   -4
    3   16   -18
    4   32   -48"""
    
    import io
    import numpy as np
    from scipy.interpolate import interp1d
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    # Load the data:
    x, y, z  = np.loadtxt(io.StringIO(u), skiprows = 1, unpack=True)
    
    x_mesh = np.linspace(0, 4, num=16)
    
    fy = interp1d(x, y, kind='cubic')
    fz = interp1d(x, z, kind='cubic')
    
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x_mesh, fy(x_mesh), fz(x_mesh), c='k', marker='s')
    ax.scatter(x, y, z, c='r', marker='o')
    plt.legend(['data'], loc='lower left',  prop={'size':12})
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    
    plt.show()