首页
学习
活动
专区
圈层
工具
发布
44 篇文章
1
机器学习需要掌握的九种工具!
2
PyAOS:大气和海洋科学Python社区
3
地球人工智能研究综述
4
优化物理和机器学习之间的协同作用
5
构建便于气象海洋应用的Anaconda环境(window版本)
6
Python结合Matlab气候数据工具箱CDT
7
用Python复现一篇Nature的研究: 1.数据下载及预处理
8
Python气象数据处理与绘图:相关性分析之散点图
9
Nature | 数据驱动的地球系统深度学习与过程理解
10
Python气象数据处理与绘图:常见的10种图像滤波方法
11
JAMES: 地球系统模式机器学习应用专刊
12
Python可视化 | xarray绘图样式配置
13
xarray系列|WRF模式前处理和后处理
14
Python可视化 | xarray一维数据绘图
15
构建适合大气与海洋应用的Anaconda环境
16
统计学中数据分析方法汇总!
17
Python可视化 | xarray 绘图时序图
18
深度学习 | 时序问题LSTM入门讲解
19
Python可视化 | xarray 二维绘图配色方案设置
20
MeteoInfoLab中如何将格点插值到站点?(附完整代码)
21
利用 pandas 和 xarray 整理气象站点数据
22
tensor与numpy数据类型转换
23
【机器学习基础】|交叉验证及Stacking
24
让数据动起来!用Python制作动画可视化效果,让数据不再枯燥!
25
数据处理 | EOF用法及可视化实例
26
数据处理 | 使用cfgrib加载GRIB文件
27
GISer如何学Python
28
数据下载 | NCEP再分析数据自动批量下载
29
关于滤波和NCL的filwgts_lanczos函数
30
数据处理 | xarray的计算距平、重采样、时间窗
31
数据处理 | xarray的NC数据基础计算(1)
32
基于Python的神经网络模型可视化绘图方法
33
python可视化 | 小波分析——​海温数据的时频域分解
34
Python精美地理可视化绘制
35
Python的常用库的数组定义及常用操作
36
Python可视化 | 温度、水深&CTRL向量空间分布图
37
python可视化 | contour、contourf、cartopy补充
38
NCL专辑 | 常用插值函数集锦
39
数值模式常用参数化方案简析及引用文献
40
数据处理与可视化 | 站点插值格点+空间区域掩膜
41
自动化工程 | 利用Python自动生成降雨量统计分析报告
42
图解NumPy:常用函数的内在机制
43
用手机运行你的Python代码
44
数据可视化 | 双Y轴可视化绘制方法(Python、R两种方法)

数据处理与可视化 | 站点插值格点+空间区域掩膜

前两天写了插值+空间掩膜的推文,不过因为数据问题删除了。 后台很多朋友留言说有需要,还是想学习一下,因此自己造了个数据再把这篇文章推一遍。

站点->格点

空间数据类型有站点数据、格点数据。 站点数据位置分布不规则,不利于可视化与分析,所以有时需要把站点数据转化成规则的、连续的格点数据。 常用的插值方法有克里金插值、径向基插值、反向权重插值......反正还挺多的,今天打算介绍一下克里金插值。

克里金插值

克里金法(Kriging)是依据协方差函数对随机过程/随机场进行空间建模和预测(插值)的回归算法。在特定的随机过程,例如固有平稳过程中,克里金法能够给出最优线性无偏估计(Best Linear Unbiased Prediction, BLUP),因此在地统计学中也被称为空间最优无偏估计器(spatial BLUP)。示意图如下:

像这种常用的算法一般都是有前人做过的,在github上一搜就能查到。 对于克里金插值可以直接调用pykrige包进行Kriging插值计算。

代码

代码语言:javascript
复制
# coding: utf-8
import math
import numpy as np
import pandas as pd
import geopandas as gpd
import xarray as xr
import salem
import cartopy.crs as ccrs
import cartopy.feature as cfeat
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
from cartopy.io.shapereader import Reader, natural_earth
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from pykrige.ok import OrdinaryKriging
import os

def create_map(fig):
    shp_path = r'/China_shp/'
    # --创建画图空间
    proj = ccrs.LambertConformal(central_longitude=110, central_latitude=35, 
                             standard_parallels=(30, 60))  # 创建坐标系

    ax = fig.subplots(1, 1, subplot_kw={'projection': proj})  
    # --设置shp
    provinces = cfeat.ShapelyFeature(
        Reader(shp_path + 'province.shp').geometries(),
        ccrs.PlateCarree(), 
        edgecolor='k',
        facecolor='none',
    )
    ax.add_feature(provinces, linewidth=0.6, zorder=2)
    # --设置范围
    ax.set_extent([80, 135, 15, 55], crs=ccrs.PlateCarree())
    # --关闭边框
    ax.spines['geo'].set_visible(False)
    # --设置刻度
    ax.tick_params(
        axis='both', 
        labelsize=5, 
        direction='out',
        labelbottom=False, 
        labeltop=False, 
        labelleft=False, 
        labelright=False
    )
    # --设置小地图
    left, bottom, width, height = 0.675, 0.13, 0.23, 0.27
    ax2 = fig.add_axes(
        [left, bottom, width, height], 
        projection=ccrs.PlateCarree()
    )
    provinces = cfeat.ShapelyFeature(
        Reader(shp_path + 'province.shp').geometries(),
        ccrs.PlateCarree(), 
        edgecolor='k',
        facecolor='gray',
    )
    ax2.add_feature(provinces, linewidth=0.6, zorder=2)
    ax2.set_extent([105, 125, 0, 25], crs=ccrs.PlateCarree())    
    return ax


def krige_interp(df):
    #插值成0.25*0.25
    grid_lon = np.arange(float(math.floor(df.lon.min())), float(math.ceil(df.lon.max())), 0.25)
    grid_lat = np.arange(float(math.floor(df.lat.min())), float(math.ceil(df.lat.max())), 0.25)
    lons = df["lon"].values
    lats = df["lat"].values
    data = df["data"].values
    
    #调用克里金插值函数
    OK = OrdinaryKriging(lons, lats, data,
                         variogram_model='gaussian',
                         coordinates_type="geographic",
                         nlags=6,)
    z, ss = OK.execute('grid', grid_lon, grid_lat)
    #转换成网格
    xgrid, ygrid = np.meshgrid(grid_lon, grid_lat)
    #将插值网格数据整理
    df_grid = pd.DataFrame(dict(lon=xgrid.flatten(), lat=ygrid.flatten()))
    #添加插值结果
    df_grid['data'] = z.flatten()
    df_grid = df_grid.set_index(['lat', 'lon'])
    ds = xr.Dataset.from_dataframe(df_grid).data
    return ds


def mask_region(ds, region='china'):
    shp_path = r'/China_shp'
    shp = gpd.read_file(shp_path + 'province.shp').set_index('省')
    if region != 'china':
        shp = shp.loc[region, :]
    ds_mask = ds.salem.roi(shape=shp)
    return ds_mask


def draw_fig(ds, levels, cmap, outpath='.'):
    fig = plt.figure(figsize=(10, 7), dpi=130)  # 创建页面
    
    im = ds.plot.contourf(
        ax=create_map(fig), 
        cmap=cmap, 
        transform=ccrs.PlateCarree(),
        levels=levels,
        add_colorbar=False
    )
    cbar_ax = fig.add_axes([0.13, 0.17, 0.3, 0.012])
    cb = fig.colorbar(im, cax=cbar_ax, orientation='horizontal')
    plt.savefig(f'{outpath}{os.sep}kriging_mask_chinamap.png')
    
if __name__ == "__main__":
    data_file = r'/testData.csv'
    levels = np.arange(116, 123, 0.5)
    cmap = 'Spectral_r'

    df = pd.read_csv(data_file, header=0, names=['lon', 'lat', 'data'])
    ds = krige_interp(df)
    ds_mask = mask_region(ds)
    draw_fig(ds_mask, levels, cmap,)

站点的密集程度对插值效果影响非常之大,由于中西部数据量比较少,所以插值结果也是没眼看。

也可以进一步调整,只留下部分省份,其余地区掩盖掉。

代码语言:javascript
复制
if __name__ == "__main__":
    data_file = r'./data.csv'
    levels = np.arange(116, 123, 0.5)
    cmap = 'Spectral_r'

    df = pd.read_csv(data_file, header=0, names=['lon', 'lat', 'data'])
    ds = krige_interp(df)
    ds_mask = mask_region(ds, region=['北京市', '天津市', '河北省', '山西省', '山东省', '辽宁省'])
    draw_fig(ds_mask, levels, cmap,)

资料获取

以上,全部。 在好奇心Log公众号后台回复克里金获取数据与代码。

ECMWF发布未来十年战略规划,包括机器学习路线图

2021-01-27

工具推荐 | Grib数据一键可视化

2021-01-27

欧洲建立地球“数字孪生体” 彻底变革气候预测

2021-01-26

2020谷歌10大领域AI技术发展(含气象)

2021-01-26

工具推荐 | 一键可视化,支持多数据格式

2021-01-22

体验南极中山站的日不落

2021-01-25

阿里云天池发布完整开源数据集(含农业遥感监测数据集)

2021-01-21

下一篇
举报
领券