python 对陆地数据进行掩膜的两种方法

简介: 一般我们分析海洋或者气象相关数据时,经常会绘制散点图分析两重变量之间的相关性。近期在分析数据时,发现有个容易出问题的情况:

前提杂谈



一般我们分析海洋或者气象相关数据时,经常会绘制散点图分析两重变量之间的相关性。近期在分析数据时,发现有个容易出问题的情况:


  • 如果我们只需要分析海洋上的某一变量的变化时,最好先将陆地数据进行掩膜,防止因为地形等原因导致陆地上的数据存在误差,影响我们的分析结果。
    基于上述需求,在这里介绍两种掩膜的方法,这里选择将陆地进行掩膜,掩膜海洋的办法类似。
  • 一种是在任何windows系统上的python自带的库进行掩膜,另一种需要通过geopandas+Salem库进行掩膜。其中,后者往往库在Windows上难以安装,一般建议在linux系统进行处理。


方法



  • 1、使用python自带的库global_land_mask进行掩膜 ( Windows/Linux都适用)
  • 2、使用geopandas+Salem进行掩膜 (建议在Linux系统上使用)


方法1:使用global_land_mask进行掩膜


这里主要通过global_land_mask中的globe.is_ocean()判断数据点的所在的经纬度坐标是否在海洋。如果是陆地,就进行掩膜,反之就不处理。下面封装一个掩膜的函数,方便后续调用处理。


所需要的库主要如下所示:

from global_land_mask import globe
import cmaps
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter


封装掩膜的函数代码如下,其中,对于不同文件的经度名称也进行了考虑设置。

def mask_land(ds, label='land', lonname='lon'):
    if lonname == 'lon':
        lat = ds.lat.data
        lon = ds.lon.data
        if np.any(lon > 180):
            lon = lon - 180
            lons, lats = np.meshgrid(lon, lat)
            mask = globe.is_ocean(lats, lons)
            temp = []
            temp = mask[:, 0:(len(lon) // 2)].copy()
            mask[:, 0:(len(lon) // 2)] = mask[:, (len(lon) // 2):]
            mask[:, (len(lon) // 2):] = temp
        else:
            lons, lats = np.meshgrid(lon, lat)# Make a grid
            mask = globe.is_ocean(lats, lons)# Get whether the points are on ocean.
        ds.coords['mask'] = (('lat', 'lon'), mask)
    elif lonname == 'longitude':
        lat = ds.latitude.data
        lon = ds.longitude.data
        if np.any(lon > 180):
            lon = lon - 180
            lons, lats = np.meshgrid(lon, lat)
            mask = globe.is_ocean(lats, lons)
            temp = []
            temp = mask[:, 0:(len(lon) // 2)].copy()
            mask[:, 0:(len(lon) // 2)] = mask[:, (len(lon) // 2):]
            mask[:, (len(lon) // 2):] = temp
        else:
            lons, lats = np.meshgrid(lon, lat)
            mask = globe.is_ocean(lats, lons)
        lons, lats = np.meshgrid(lon, lat)
        mask = globe.is_ocean(lats, lons)
        ds.coords['mask'] = (('latitude', 'longitude'), mask)
    if label == 'land':
        ds = ds.where(ds.mask == True)
    elif label == 'ocean':
        ds = ds.where(ds.mask == False)
    return ds


这个函数调用起来非常简单,只需要输入你的数据,选择掩膜的区域是海洋和陆地,指定经度名称即可。


下面以月均海温资料为例,展示掩膜前后的效果:


2bd185809eb54bf9a580c8445d0a0a0a.png

可以发现,掩膜成功,效果还是不错的。基本满足我们下一步的处理需求。绘图代码如下:

infile = xr.open_dataset(r"sst.mnmean.nc")
infile = mask_land(infile,'land','lon')
infile = infile.transpose("time","lat","lon",...)
def make_map(ax, title):
    # set_extent  set crs
    ax.set_extent(box, crs=ccrs.PlateCarree())
    # land = cfeature.NaturalEarthFeature('physical',
    #                                     'land',
    #                                     scale,
    #                                     edgecolor='face')
    ax.set_xticks(np.arange(box[0], box[1] + xstep, xstep),
                  crs=ccrs.PlateCarree())  # [ )
    ax.set_yticks(np.arange(box[2], box[3] + ystep, ystep),
                  crs=ccrs.PlateCarree())
    plt.tick_params(labelsize=15)
    lon_formatter = LongitudeFormatter(zero_direction_label=False)  
    lat_formatter = LatitudeFormatter()
    ax.gridlines()
    ax.xaxis.set_major_formatter(lon_formatter)
    ax.yaxis.set_major_formatter(lat_formatter)
    ax.set_ylabel('Latitude', fontsize=15)
    ax.set_xlabel('Longitute', fontsize=15)
    ax.set_title(title, fontsize=23, loc='left')
    return ax
lat = infile['lat'].data
lon = infile['lon'].data
sst = infile['sst'].data
sst_m=np.nanmean(sst,axis=0)
sst_ori = xr.open_dataset(r"sst.mnmean.nc").sst
sst_ori = np.nanmean(sst_ori,axis=0)
box = [0, 361, -90, 85]  
scale = '50m'            
xstep, ystep = 45, 35   
# cmap=plt.get_cmap('rainbow')#'RdYlBu_r'
cmap=cmaps.NCV_jet
fig=plt.figure(figsize=(20,16))
ax=fig.add_subplot(121,projection=ccrs.PlateCarree(central_longitude=180))
make_map(ax,'SST-Mask data')
ax.contourf(lon,lat,sst_m,cmap=cmap,transform=ccrs.PlateCarree(),zorder=2)
ax2=fig.add_subplot(122,projection=ccrs.PlateCarree(central_longitude=180))
make_map(ax2,'SST-origin data')
plot=ax2.contourf(lon,lat,sst_ori,cmap=cmap,transform=ccrs.PlateCarree(),zorder=2)
ax3=fig.add_axes([0.27,0.3,0.4,0.017])
cb=fig.colorbar(plot,cax=ax3,shrink=0.9,ticks=[0,10,20,30],pad=0.04,aspect=15,orientation='horizontal')
cb.ax.tick_params(labelsize=10)
cb.ax.set_title('$°C$', fontsize=20, loc='center')


方法2:使用geopandas+salem库进行掩膜


关于salem和geopandas在Windows系统的安装可以查看以下帖子,可能有用:

salem安装

geopandas安装


使用geopandas+salem进行掩膜相比上述方法,大大减少了代码量,非常方便简洁,只需要提供数据和一个海洋的shp文件即可。缺点在于geopanda和Salem在windows系统的安装较为困难,很难成功安装使用。但是,在linux系统下则相对来说比较容易安装。这里也在Linux系统下以对垂直速度的数据的掩膜进行演示:

我这里的数据的经度排序是0~360,先将其转为-180~180排列,方便我后续处理使用:


import salem
import geopandas as geo
import xarray as xr
ds=xr.open_dataset("omiga.nc")
# change 0-360 to -180 ~ 180
lon_name = 'lon'
ds['longitude_adjusted'] = xr.where(
    ds[lon_name] > 180,
    ds[lon_name] - 360,
    ds[lon_name])
ds = (ds.swap_dims({lon_name: 'longitude_adjusted'}).sel(**{'longitude_adjusted': sorted(ds.longitude_adjusted)}).drop(lon_name))
ds = ds.rename({'longitude_adjusted': lon_name})
# mask
shp_path="shp/10m_physical/ne_10m_ocean_scale_rank.shp"
shp=geo.read_file(shp_path)
sst=ds.salem.roi(shape=shp)
sst.to_netcdf(path="omiga_mask.nc")


绘制填色图查看掩膜结果:


294c8ac69f6a4cff91e8268b8700e505.png

总体上还不错,绘图代码这里就不贴了,与方法1中的代码一致。

虽然不同的掩膜方法掩膜的结果可能不同,但是基本上满足我们后续的计算需求,只需要统一掩膜方法即可。有兴趣的xd可以尝试起来。


                        一个努力学习python的海洋人
                        水平有限,欢迎指正!!!
                          欢迎评论、收藏、点赞、转发、关注。
                          关注我不后悔,记录学习进步的过程~~


相关文章
|
1月前
|
测试技术 API Python
【10月更文挑战第1天】python知识点100篇系列(13)-几种方法让你的电脑一直在工作
【10月更文挑战第1天】 本文介绍了如何通过Python自动操作鼠标或键盘使电脑保持活跃状态,避免自动息屏。提供了三种方法:1) 使用PyAutoGUI,通过安装pip工具并执行`pip install pyautogui`安装,利用`moveRel()`方法定时移动鼠标;2) 使用Pymouse,通过`pip install pyuserinput`安装,采用`move()`方法移动鼠标绝对位置;3) 使用PyKeyboard,同样需安装pyuserinput,模拟键盘操作。文中推荐使用PyAutoGUI,因其功能丰富且文档详尽。
WK
|
22天前
|
Python
Python中format_map()方法
在Python中,`format_map()`方法用于使用字典格式化字符串。它接受一个字典作为参数,用字典中的键值对替换字符串中的占位符。此方法适用于从字典动态获取值的场景,尤其在处理大量替换值时更为清晰和方便。
WK
68 36
|
27天前
|
数据采集 JSON 数据处理
抓取和分析JSON数据:使用Python构建数据处理管道
在大数据时代,电商网站如亚马逊、京东等成为数据采集的重要来源。本文介绍如何使用Python结合代理IP、多线程等技术,高效、隐秘地抓取并处理电商网站的JSON数据。通过爬虫代理服务,模拟真实用户行为,提升抓取效率和稳定性。示例代码展示了如何抓取亚马逊商品信息并进行解析。
抓取和分析JSON数据:使用Python构建数据处理管道
|
1月前
|
机器学习/深度学习 数据采集 数据挖掘
11种经典时间序列预测方法:理论、Python实现与应用
本文将总结11种经典的时间序列预测方法,并提供它们在Python中的实现示例。
63 2
11种经典时间序列预测方法:理论、Python实现与应用
|
11天前
|
图形学 Python
SciPy 空间数据2
凸包(Convex Hull)是计算几何中的概念,指包含给定点集的所有凸集的交集。可以通过 `ConvexHull()` 方法创建凸包。示例代码展示了如何使用 `scipy` 库和 `matplotlib` 绘制给定点集的凸包。
21 1
|
12天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
13天前
|
数据采集 Web App开发 iOS开发
如何使用 Python 语言的正则表达式进行网页数据的爬取?
使用 Python 进行网页数据爬取的步骤包括:1. 安装必要库(requests、re、bs4);2. 发送 HTTP 请求获取网页内容;3. 使用正则表达式提取数据;4. 数据清洗和处理;5. 循环遍历多个页面。通过这些步骤,可以高效地从网页中提取所需信息。
|
25天前
|
数据可视化 算法 JavaScript
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
本文探讨了如何利用图论分析时间序列数据的平稳性和连通性。通过将时间序列数据转换为图结构,计算片段间的相似性,并构建连通图,可以揭示数据中的隐藏模式。文章介绍了平稳性的概念,提出了基于图的平稳性度量,并展示了图分区在可视化平稳性中的应用。此外,还模拟了不同平稳性和非平稳性程度的信号,分析了图度量的变化,为时间序列数据分析提供了新视角。
53 0
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
|
29天前
|
开发者 Python
Python中的魔法方法与运算符重载
在Python的奇妙世界里,魔法方法(Magic Methods)和运算符重载(Operator Overloading)是两个强大的特性,它们允许开发者以更自然、更直观的方式操作对象。本文将深入探讨这些概念,并通过实例展示如何利用它们来增强代码的可读性和表达力。
|
1月前
|
自然语言处理 算法 数据挖掘
探讨如何利用Python中的NLP工具,从被动收集到主动分析文本数据的过程
【10月更文挑战第11天】本文介绍了自然语言处理(NLP)在文本分析中的应用,从被动收集到主动分析的过程。通过Python代码示例,详细展示了文本预处理、特征提取、情感分析和主题建模等关键技术,帮助读者理解如何有效利用NLP工具进行文本数据分析。
46 2