【问题标题】:How to interpolate data by latitudes and longitudes?如何按纬度和经度插值数据?
【发布时间】:2021-05-07 17:54:19
【问题描述】:

我有一个包含非结构化数据、纬度和经度的数据集

如何通过反距离加权对数据进行插值?

当我使用scipy.griddata时,90度仰角周围的点是不合理的

有什么解决办法吗?

谢谢。

【问题讨论】:

    标签: python python-3.x matplotlib scipy


    【解决方案1】:

    您可以尝试使用plotly 绘制它,它会为您提供交互式绘图。您可以验证terrain 中每个点的值。

    详情可参考以下代码。

    import plotly.graph_objects as go
    import numpy as np
    import pandas as pd
    
    # Read data from a csv
    url = 'https://raw.githubusercontent.com/patel999jay/Bedford_python/master/bathy_bedford.csv'
    z_data = pd.read_csv(url)
    # z_data.head() # to see dataframe head
    # Read data from a csv
    url = 'https://raw.githubusercontent.com/patel999jay/Bedford_python/master/bathy_bedford.csv'
    z_data = pd.read_csv(url, index_col=0)
    
    z = z_data.values
    sh_0, sh_1 = z.shape
    x, y = np.linspace(44.66875, 44.74791667, sh_0), np.linspace(-63.69791667, -63.52708333, sh_1) # This is lat and long
    fig = go.Figure(data=[go.Surface(z=z, x=x, y=y,colorscale='Viridis')])
    fig.update_traces(contours_z=dict(show=True, usecolormap=True,
                                      highlightcolor="limegreen", project_z=True))
    fig.update_layout(title='Bedford Basin Elevation',xaxis_title="Latitude", 
                      yaxis_title="Longitude",autosize=False,
                      width=900, height=900, 
                      margin=dict(l=65, r=50, b=65, t=90))
    fig.update_layout(scene = dict(
                        xaxis_title='Latitude',
                        yaxis_title='Longitude',
                        zaxis_title='Elevation'),
                        margin=dict(r=20, b=10, l=10, t=10))  
    fig.update_layout(coloraxis_colorbar=dict(
        title="Elevation",
        thicknessmode="pixels", thickness=50,
        lenmode="pixels", len=200,
        yanchor="top", y=1,
        ticks="outside", ticksuffix="",
        dtick=5
    ))
    fig.show()
    

    如果你想使用matplotlib,那么你可以参考下面的代码。

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import cm
    import matplotlib.gridspec as gridspec
    import matplotlib as mpl
    # from matplotlib.ticker import LinearLocator, FormatStrFormatter
    from matplotlib import rc, rcParams
    from mpl_toolkits.mplot3d import Axes3D
    from scipy.interpolate import griddata
    import pandas as pd
    
    url ="https://raw.githubusercontent.com/patel999jay/Bedford_python/master/POINT_DATA_TITLE.csv"
    df = pd.read_csv(url)
    # df.head() # see dataframe head
    
    # 2D-arrays from DataFrame
    x1 = np.linspace(df['x'].min(), df['x'].max(), len(df['x'].unique()))
    y1 = np.linspace(df['y'].min(), df['y'].max(), len(df['y'].unique()))
    
    """
    x, y via meshgrid for vectorized evaluation of
    2 scalar/vector fields over 2-D grids, given
    one-dimensional coordinate arrays x1, x2,..., xn.
    """
    
    x2, y2 = np.meshgrid(x1, y1)
    
    # Interpolate unstructured D-dimensional data.
    z2 = griddata((df['x'], df['y']), df['z'], (x2, y2), method='cubic')
    
    # Ready to plot
    
    fig = plt.figure(211,figsize=(15,20))
    ax = fig.add_subplot(211, projection='3d')
    spec = gridspec.GridSpec(ncols=1, nrows=2,
                             height_ratios=[4, 1])
    
    surf = ax.plot_surface(x2, y2, z2, rstride=1, cstride=1, cmap=cm.terrain,
                           linewidth=1, antialiased=False)
    ax.view_init(25,-55)
    
    cset = ax.contourf(x2, y2, z2, zdir='z2', offset=-5, cmap=cm.terrain, antialiased=True)
    
    rcParams['legend.fontsize'] = 20
    
    rc('text', usetex=True)
    rc('axes', linewidth=2)
    rc('font', weight='bold')
    
    ax.xaxis.set_tick_params(labelsize=20)
    ax.yaxis.set_tick_params(labelsize=20)
    ax.zaxis.set_tick_params(labelsize=20)
    ax.set_zticks([-70, -50, -30, -10, 10, 30, 50, 70, 90, 110])
    plt.title(r'\textbf{Bedford Basin Bathymatry}', fontsize=20)
    plt.xlabel(r'\textbf{Latitude}', fontsize=20, labelpad= 23)
    plt.ylabel(r'\textbf{Longitude}', fontsize=20, labelpad= 20)
    ax.set_zlabel(r'\textbf{Elevation}', fontsize=20, labelpad= 10)
    

    P.S.:您能否提供您的问题的最小可复制示例,然后我可以相应地更新我的答案。现在我正在使用随机数据。

    【讨论】:

    • 感谢您的回答。随机数据没问题。我使用gridara 作为您的方式。 griddata 使用三个附近的点来内插目标点。二维地图没问题。当我们用它通过经纬度对球体或半球上的点进行插值时,它对大多数区域也有好处,但对于边界上的点就不好了。因为点 (0,0) 和 (0,360) 之间的距离对于 2d 地图来说很远。
    • 您可以使用不同的interpolation 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多