【发布时间】:2021-05-07 17:54:19
【问题描述】:
我有一个包含非结构化数据、纬度和经度的数据集
如何通过反距离加权对数据进行插值?
当我使用scipy.griddata时,90度仰角周围的点是不合理的
有什么解决办法吗?
谢谢。
【问题讨论】:
标签: python python-3.x matplotlib scipy
我有一个包含非结构化数据、纬度和经度的数据集
如何通过反距离加权对数据进行插值?
当我使用scipy.griddata时,90度仰角周围的点是不合理的
有什么解决办法吗?
谢谢。
【问题讨论】:
标签: python python-3.x matplotlib scipy
您可以尝试使用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 方法。