如何在Python中将散乱数据插入到常规网格中?
我有来自英国分散气象站的经度,纬度和温度的三个txt文件(或者说三个列表lon,lat,temp)。我想首先插入这些数据,以获得一个漂亮的彩色温度图。然后,我想在土地面具上绘制这个内插温度层(因此在英国岛上,而不是在海上)。这可能与Python有关吗?
这听起来像是一个GIS堆栈交换的问题 - [farrenthorpe于](https://earthscience.stackexchange.com/users/543/farrenthorpe "声誉8,780") [8月11日'17在18:21](https://earthscience.stackexchange.com/questions/12057/how-to-interpolate-scattered-data-to-a-regular-grid-in-python#comment21926_12057)
3答案
使用,和numpy
,这是直截了当的。这是一个例子:scipy.interpolate.griddata``matplotlib
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import griddata
# data coordinates and values
x = np.random.random(100)
y = np.random.random(100)
z = np.random.random(100)
# target grid to interpolate to
xi = yi = np.arange(0,1.01,0.01)
xi,yi = np.meshgrid(xi,yi)
# set mask
mask = (xi > 0.5) & (xi < 0.6) & (yi > 0.5) & (yi < 0.6)
# interpolate
zi = griddata((x,y),z,(xi,yi),method='linear')
# mask out the field
zi[mask] = np.nan
# plot
fig = plt.figure()
ax = fig.add_subplot(111)
plt.contourf(xi,yi,zi,np.arange(0,1.01,0.01))
plt.plot(x,y,'k.')
plt.xlabel('xi',fontsize=16)
plt.ylabel('yi',fontsize=16)
plt.savefig('interpolated.png',dpi=100)
plt.close(fig)
结果:
如何使用:
-
x
并且y
是点的位置 - 这些点对应于您的站点lon
和lat
值; -
z
是点的值 - 这对应于站点的温度观测值; -
xi
并且yi
是目标网格轴 - 这些将是您的目标经度和纬度坐标,它必须与您的landmask字段匹配; -
zi
是结果; - 此示例包含一种掩盖字段的简单方法。您应该使用网格上的landmask替换此掩码。
还要注意method
参数griddata
。此外linear
,这也可以是cubic
或nearest
。我建议你一起玩,看看是什么产生了你的数据集的最佳结果。
谢谢你。有没有一种简单的方法可以使用matplotlib仅在土地上绘图?显然我不能使用(mask =(xi> 0.5)&(xi <0.6)&(yi> 0.5)&(yi <0.6))来定义英国的土地面具, - Stavros Keppas, 17年8月12日在13:15
您需要掩码数据,例如2-d场,水上零和陆地上的零。如果你没有,你可以根据地形数据制作一个,例如我经常用于此目的的ETOPO 01。 - 米兰科西奇 于 2017年8月12日15:21
-
因为我是python中的新手你能不能给我一个更详细的描述怎么做? - Stavros Keppas, 17年8月13日12:18
@StavrosKeppas在某些时候你必须自己尝试。如果您在此处发布,或在GIS stackexchange中发布,或者在stackoverflow中发布,您应该尽可能地尝试。“请写下我需要的程序”问题通常没有答案。学习使用python的最好方法是尝试一段时间。如果它不起作用,那么您发布不起作用的代码并寻求帮助。这显示了努力,这是一个很大的优点,并可能鼓励更多有用的答案。此外,您可以根据需要提出尽可能多的(好)问题,不要在评论中继续提出问题。 - - 1817年 8月13日13:41
这个简单任务的最简单的解决方案是使用GIS软件,例如免费的QGIS。添加分隔文本图层并尝试栅格插值。下载一个免费的海岸线矢量,并用海岸线剪辑你的光栅。如果您遇到困难,GIS SE上的一些搜索可以帮助您。使用GIS选项,还可以轻松绘制例如城市或绘制位置的插值温度。
或者(根据您更新的问题),您可以使用Python。这将以某种方式让您更好地控制您的工作流程。底图是一个有用的包,请参阅本教程的开头部分。Python也是免费的,SE和其他地方都有一个很棒的社区。numpy和scipy是插值和所有数组进程的好包。对于更复杂的空间过程(从矢量多边形剪辑栅格,例如)GDAL是一个很棒的库。
如果您打算稍后进行更苛刻的统计分析,也可以使用R,这可能是一个智能解决方案。有一些教程可以让你走上正轨。
GMT还应该能够满足您的需求并且有一个python接口,至少在开发中。
您可能需要花费一些精力来选择正确的插值方法,并确保您的网格是实际值的最佳估计值。
享受您的地图制作!
更新:
我认为GIS将是第一种方法,但是当你要求一些Python命令时,这里有一个如何使用Python,底图和scipy为你的应用程序的草率示例。通过从shapefile创建一个掩码可以大大改善它,如上所述,它可以灵敏地使用插值方法。
import numpy as np
from scipy.interpolate import griddata
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
#Define mapframe
lllon = -11
lllat = 49
urlon = 2
urlat = 61
# Make some toy data, random points + corners
n = 10 # no of stations
lat = np.random.uniform(low=lllat+2, high=urlat-2, size=n)
lat = np.append(lat, [lllat, urlat, urlat, lllat])
lon = np.random.uniform(low=lllon+2, high=urlon-2, size=n)
lon = np.append(lon, [lllon, urlon, lllon, urlon])
temp = np.random.randn(n+4) + 8 # British summer?
# set up basemap chose projection!
m = Basemap(projection = 'merc', resolution='i',
llcrnrlon = lllon, llcrnrlat = lllat, urcrnrlon = urlon, urcrnrlat = urlat)
# transform coordinates to map projection m
m_lon, m_lat = m(*(lon, lat))
# generate grid data
numcols, numrows = 240, 240
xi = np.linspace(m_lon.min(), m_lon.max(), numcols)
yi = np.linspace(m_lat.min(), m_lat.max(), numrows)
xi, yi = np.meshgrid(xi, yi)
# interpolate, there are better methods, especially if you have many datapoints
zi = griddata((m_lon,m_lat),temp,(xi,yi),method='cubic')
fig, ax = plt.subplots(figsize=(12, 12))
# draw map details
m.drawmapboundary(fill_color = 'skyblue', zorder = 1)
# Plot interpolated temperatures
m.contourf(xi, yi, zi, 500, cmap='magma', zorder = 2)
m.drawlsmask(ocean_color='skyblue', land_color=(0, 0, 0, 0), lakes=True, zorder = 3)
cbar = plt.colorbar()
plt.title('Temperature')
plt.show()
(这是修改后的代码,用于其他内容。对于详细问题,其他论坛更适合。)
分享改善这个答案
(https://earthscience.stackexchange.com/posts/12059/revisions "显示对此帖子的所有修改")
谢谢你。但是,你能为python提供一些命令吗? - Stavros Keppas 于 18年8月11日15:17
那个底图插值教程没有做到Stavros正在寻找的东西。 - milancurcic 17年 8月11日18:42
@milancurcic不,但它可以让他走上正轨。numpy和scipy是插值和所有数组进程的好包,如您的示例所示。棘手的事情往往是让底图做一个打算做的事情。 - Tactopoda 于 2012年8月11日23:08
@StavrosKeppas我添加了一些代码,但我首先要去GIS。 - Tactopoda 于 2017年8月13日15:43
谢谢。真好。我也想绘制海岸线。我添加了这两行:m.drawcoastlines()m.drawcountries()但是我得到的海岸线不是连续的线