python–读取TRMM-3B43月平均降水绘制气候态空间分布图(陆地区域做掩膜)

成果展示

TRMM降水数据介绍

热带降雨测量任务(The Tropical Rainfall Measuring Mission,TRMM)是美国国家航空航天局(NASA)和日本国家太空发展署(National Space Development Agency)的一项联合太空任务,旨在监测和研究热带和亚热带降雨及其相关的能量释放。该任务使用5种仪器: 降水雷达(Precipitation Radar,PR)、 TRMM 微波成像仪(TRMM Microwave Imager,TMI)、可见红外扫描仪(Visible Infrared Scanner,VIRS)、云与地球辐射能量系统(Clouds & Earths Radiant Energy System,CERES)和闪电成像传感器(Lightning Imaging Sensor,LSI)。TMI 和 PR 是用于降水的主要仪器。这些仪器被用于形成 TRMM 多卫星降水分析(TRMM Multi-satellite Precipitation Analysis,TMPA)的 TRMM 组合仪器(TRMM Combined Instrument ,TCI)校准数据集(TRMM 2B31)的算法中,其 TMPA 3B43月平均降水量TMPA 3B42日平均和次日(3小时)平均是最相关的 TRMM 相关气候研究的产品。3B42和3B43的空间分辨率为0.25 ° ,1998年至今覆盖北纬50 ° 至南纬50 ° 。


本文中用到的数据主要为TRMM-3B43月平均产品,用于绘制降水的气候态空间分布图

TRMM-3B43产品如下所示:

  • 空间分辨率:0.25°
  • 时间覆盖范围:1999.01 - 2020.01
  • 经纬度范围: 经度:0-360°,纬度:-50°S-50°N
  • 单位为:mm/hour
  • 降水类型 : 累计降水

这里使用的python系统环境:linux系统,因为windows上好多库都不好用

关于掩膜的方法,之前出过教程了,这里不再重复:

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


官网数据下载链接


数据处理

  • 这里所使用的3B43降水资料数据为.HDF格式,因此需要使用pyhdf这个库来读取,不习惯的可以下载netcdf的数据格式
  • 由于数据中缺少经纬度信息(也可能是我没有找到),为了实现区域切片,这里手动造了一个dataarray的数据,从而实现切片的过程
  • 数据中读取的变量为precipitation,读取完之后是个二维的数组,为了给他加上时间纬度,所以手动给他进行了扩维,之后实现多年的气候态平均计算
  • 使用global_land_mask实现对于陆地区域的掩膜处理
  • 使用cnmaps 实现中国的区域绘制,这里的cnmaps的库在windows上可能不好安装,也直接使用cartopyax.coastlines('50m')自带的海岸线
  • 将原始数据单位转化为 mm/year,这里只是简单的转换*24*365

代码实现

1、首先读取10年的数据路径

import xarray as xr
import os,glob
import numpy as np
from pyhdf.SD import SD
path = '/Datadisk/TRMM/3B43/'
file_list = []
for year in range(2009,2019):folder = os.path.join(path, str(year))file_name = glob.glob(folder+'/3B43.'+str(year)+'*.HDF')file_name.sort()file_list.extend(file_name)
file_list.sort()


2、封装数据读取函数,并对需要的区域进行切片,我选择的区域为经度:[90.0, 145],纬度:[-10, 55],并将循环读取的10年月平均数组创建为dataarray的格式方面后续掩膜,这里的时间可以通过pandas自己创建时间序列,我这里偷懒直接读取了之前处理过的月平均gpcp的time了

dt = xr.open_dataset("/gpcp_monthly_mask.nc")
precip = dt.sel(time=slice('2009','2018'),lat =slice(-10,55),lon = slice(90,145)).precip
time_num = precip.time.values
def get_data(path,time):da = SD(path)pre = da.select('precipitation')[:]pre = np.expand_dims(pre,axis=0)lon = np.arange(-180,180.,0.25)lat = np.arange(-50,50.,0.25)time = time
#   time = datetime.datetime.utcfromtimestamp(tim).strftime('%Y-%m-%d %H:%M:%S')da = xr.DataArray(pre, dims=['time','lon','lat'],coords=dict(lon=(['lon'], lon),lat=(['lat'], lat),time=(['time'],[time])),)##############################################################################lon_range = [90.0, 145]lat_range = [-10, 55]da = da.sel(lon=slice(*lon_range), lat=slice(*lat_range))x ,y = da.lon,da.lat   return da,x,y
rain = np.zeros((len(file_list),221,240))
for i in range(len(file_list)):print(i)da,x,y =  get_data(file_list[i], time_num[i])rain[i] = da
ds = xr.DataArray(rain, dims=['time','lon','lat'],coords=dict(lon=(['lon'], x.data),lat=(['lat'], y.data),time=(['time'],time_num)),)

3、对数据的陆地部分进行掩膜,并计算气候态平均,转换单位为mm/year

from global_land_mask import globe
def mask_land(ds, label='land', lonname='lon'):if lonname == 'lon':lat = ds.lat.datalon = ds.lon.dataif np.any(lon > 180):lon = lon - 180lons, 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):] = tempelse:lons, lats = np.meshgrid(lon, lat)# Make a gridmask = globe.is_ocean(lats, lons)# Get whether the points are on ocean.ds.coords['mask'] = (('lat', 'lon'), mask)elif lonname == 'longitude':lat = ds.latitude.datalon = ds.longitude.dataif np.any(lon > 180):lon = lon - 180lons, 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):] = tempelse: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
data =  mask_land(ds,'land')
precip_mean = np.nanmean(data*24*365,axis=0)

4、绘图,保存图片

import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
import cmaps
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.ticker as mticker
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cnmaps import get_adm_maps, draw_maps
box = [100,140,0,50]
xstep,ystep = 10,10
proj = ccrs.PlateCarree(central_longitude=180)
plt.rcParams['font.family'] = 'Times New Roman',
fig = plt.figure(figsize=(8,7),dpi=200)
fig.tight_layout()
ax = fig.add_axes([0.1,0.2,0.8,0.7],projection = proj)
ax.set_extent(box,crs=ccrs.PlateCarree())
draw_maps(get_adm_maps(level='国')) #这里如果库不好安装的话可以使用下面注释的代码,cartopy自带的海岸线
# ax.coastlines('50m')
ax.set_xticks(np.arange(box[0],box[1]+xstep, xstep),crs=ccrs.PlateCarree())
ax.set_yticks(np.arange(box[2], box[3]+1, ystep),crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter(zero_direction_label=False)#True/False
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.set_title('TRMM(mm/year)',fontsize=16,pad=8,loc='left')
ax.tick_params(    which='both',direction='in',width=0.7,pad=8, labelsize=14,bottom=True, left=True, right=True, top=True)c = ax.contourf(x,y,precip_mean.T,levels=np.arange(200,3300,100),extend='both',transform=ccrs.PlateCarree(),cmap=cmaps.NCV_jet)
cb=plt.colorbar(c,shrink=0.98,orientation='vertical',aspect=28,)
cb.ax.tick_params(labelsize=10,which='both',direction='in',)
plt.show()
fig.savefig('./TRMM_10year_monthly.png',dpi=500)

全部代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri May  5 09:45:08 2023@author: %(jixianpu)sEmail : 211311040008@hhu.edu.cnintroduction : keep learning althongh walk slowly
"""
import xarray as xr
import os,glob
import numpy as np
from pyhdf.SD import SD
path = '/Datadisk/TRMM/3B43/'
file_list = []
for year in range(2009,2019):folder = os.path.join(path, str(year))file_name = glob.glob(folder+'/3B43.'+str(year)+'*.HDF')file_name.sort()file_list.extend(file_name)file_list.sort()
dt = xr.open_dataset("/gpcp_monthly_mask.nc")
precip = dt.sel(time=slice('2009','2018'),lat =slice(-10,55),lon = slice(90,145)).precip
time_num = precip.time.valuesdef get_data(path,time):da = SD(path)pre = da.select('precipitation')[:]pre = np.expand_dims(pre,axis=0)lon = np.arange(-180,180.,0.25)lat = np.arange(-50,50.,0.25)time = time
#   time = datetime.datetime.utcfromtimestamp(tim).strftime('%Y-%m-%d %H:%M:%S')da = xr.DataArray(pre, dims=['time','lon','lat'],coords=dict(lon=(['lon'], lon),lat=(['lat'], lat),time=(['time'],[time])),)
##############################################################################lon_range = [90.0, 145]lat_range = [-10, 55]da = da.sel(lon=slice(*lon_range), lat=slice(*lat_range))x ,y = da.lon,da.lat    return da,x,yrain = np.zeros((len(file_list),221,240))
for i in range(len(file_list)):print(i)da,x,y =  get_data(file_list[i], time_num[i])rain[i] = da
ds = xr.DataArray(rain, dims=['time','lon','lat'],coords=dict(lon=(['lon'], x.data),lat=(['lat'], y.data),time=(['time'],time_num)),)
from global_land_mask import globe
def mask_land(ds, label='land', lonname='lon'):if lonname == 'lon':lat = ds.lat.datalon = ds.lon.dataif np.any(lon > 180):lon = lon - 180lons, 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):] = tempelse:lons, lats = np.meshgrid(lon, lat)# Make a gridmask = globe.is_ocean(lats, lons)# Get whether the points are on ocean.ds.coords['mask'] = (('lat', 'lon'), mask)elif lonname == 'longitude':lat = ds.latitude.datalon = ds.longitude.dataif np.any(lon > 180):lon = lon - 180lons, 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):] = tempelse: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
data =  mask_land(ds,'land')
precip_mean = np.nanmean(data*24*365,axis=0)
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
import cmaps
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.ticker as mticker
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cnmaps import get_adm_maps, draw_maps
box = [100,140,0,50]
xstep,ystep = 10,10
proj = ccrs.PlateCarree(central_longitude=180)
plt.rcParams['font.family'] = 'Times New Roman',
fig = plt.figure(figsize=(8,7),dpi=200)
fig.tight_layout()
ax = fig.add_axes([0.1,0.2,0.8,0.7],projection = proj)
ax.set_extent(box,crs=ccrs.PlateCarree())
draw_maps(get_adm_maps(level='国'))
# ax.coastlines('50m')
ax.set_xticks(np.arange(box[0],box[1]+xstep, xstep),crs=ccrs.PlateCarree())
ax.set_yticks(np.arange(box[2], box[3]+1, ystep),crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter(zero_direction_label=False)#True/False
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.set_title('TRMM(mm/year)',fontsize=16,pad=8,loc='left')
ax.tick_params(    which='both',direction='in',width=0.7,pad=8, labelsize=14,bottom=True, left=True, right=True, top=True)c = ax.contourf(x,y,precip_mean.T,levels=np.arange(200,3300,100),extend='both',transform=ccrs.PlateCarree(),cmap=cmaps.NCV_jet)
cb=plt.colorbar(c,shrink=0.98,orientation='vertical',aspect=28,)
cb.ax.tick_params(labelsize=10,which='both',direction='in',)
plt.show()
fig.savefig('./TRMM_10year_monthly.png',dpi=500)

引用参考

TRMM: Tropical Rainfall Measuring Mission
https://climatedataguide.ucar.edu/climate-data/trmm-tropical-rainfall-measuring-mission

Monthly 0.25° x 0.25° TRMM multi-satellite and Other Sources Rainfall (3B43)
http://apdrc.soest.hawaii.edu/datadoc/trmm_3b43.php

TRMM 3B43: Monthly Precipitation Estimates
https://developers.google.com/earth-engine/datasets/catalog/TRMM_3B43V7

中巴经济走廊TRMM_3B43月降水数据(1998-2017年):http://www.ncdc.ac.cn/portal/metadata/4b9504fa-0e34-47c9-a755-91d3f3253312

TRMM (TMPA/3B43) Rainfall Estimate L3 1 month 0.25 degree x 0.25 degree V7 (TRMM_3B43)(GES 官网介绍):https://disc.gsfc.nasa.gov/datasets/TRMM_3B43_7/summary

国家海洋遥感在线分析平台 https://www.satco2.com/index.php?m=content&c=index&a=show&catid=317&id=217

之前没怎么处理过程HDF的文件,时间仓促,只是简单了记录了一下,没有考虑代码的美观和计算的高效性,欢迎大家评论或者联系我进行交流讨论~~

python--读取TRMM-3B43月平均降水绘制气候态空间分布图(陆地区域做掩膜)相关推荐

  1. python读取CSV文件中温度值绘制3D折线图

    import pyecharts.options as opts from pyecharts.charts import Line3D import random import csv filena ...

  2. python读取图像并相加_python给图像加上mask,并提取mask区域实例

    python对图像提取mask部分: 代码: #coding:utf-8 import os import cv2 import numpy as np def add_mask2image_bina ...

  3. Python读取TMRR3B43 月降雨量数据Hdf文件

    下面展示 读取TRMM 3B43类,实现 1.查看HDF文件属性 2.查看数据集的属性 3.读取数据集 4.计算月降雨量,原始数据为mm/h计算为mm/month. class ReadAndWrit ...

  4. 1950—2022年逐年平均降水栅格数据(全国/分省)

    气象数据是在各项研究中都经常使用的数据,而降水又是最常用的气象指标!之前我们分享过1950-2022年逐月的平均降水栅格数据(可查看之前的文章获悉详情),数据来源于欧盟及欧洲中期天气预报中心等组织发布 ...

  5. python读取fnl数据计算200-800km范围内的区域平均、散度、涡度实现grads函数

    之前的气象数据如从NCEP中下载的FNL数据一般都是采用Grads处理,但Grads的代码语言比较繁杂,而且一般只用来处理气象数据,所以逐渐都不维护了.作为新生代的python,可以用来解决很多,因此 ...

  6. 6月29日云栖精选夜读:Java、PHP、Python、JS 等开发者都如何绘制统计图

    原文链接 目前很多程序员绘图基本上都是采用后端生成数据传递给前端,然后前端将数据渲染到绘图库上面进行显示,从而得到我们最后看到的各种图,但是有时候,我们发现需要传递的数据很多很多,那么这个时候如果将数 ...

  7. 用python读取csv文件并绘制波形及频谱

    最近想用python处理一下故障录波数据,于是学习了一下python.我一直对数据绘图比较感兴趣,学了一点皮毛之后感觉还挺好用的,这一点python和matlab/octave是非常相近的. 先说一下 ...

  8. python读取文本数据绘制曲线图

    目录 写在前面 代码 reference 写在前面 1.本文内容 python读取文本数据曲线图 2.转载请注明出处: https://blog.csdn.net/qq_41102371/articl ...

  9. 使用python读取excel中的数据,并绘制折线图

    使用python读取excel中的数据,并绘制折线图 做实验的时候采集到一些数据,从文本拷贝到excel,然后从十六进制转换成十进制.图表是分析数据的有利工具,使用python绘制出的图表简明美观.所 ...

最新文章

  1. android之数据存储,Android数据存储之File
  2. iOS友盟推送发送失败
  3. 为衣服添加NFC功能:挥下袖子就能安全支付,打开车门坐进去就能启动汽车|Nature子刊...
  4. Apache Kafka-初体验Kafka(03)-Centos7下搭建kafka集群
  5. hdu 4348 To the moon (主席树)
  6. exc读入到matlab,matlab外部程序接口-excel
  7. 在Packet Tracer中路由器静态路由配置
  8. 二叉排序树的插入 java_leetcode刷题笔记-701. 二叉搜索树中的插入操作(java实现)...
  9. 专业管理系统-包含VB源代码(数据库)
  10. Centos中重置MySQL密码
  11. 免费申请ssl证书并部署
  12. win10 更新后任务栏问题及如何关闭windows自动更新
  13. 蓝牙定位技术原理--蓝牙人员定位--蓝牙定位--新导智能
  14. MATLAB中subs函数
  15. 英语发音规则---ea字母组合发音规律
  16. 计算机u盘打不开怎么办,电脑*u盘打不开怎么办
  17. [思想][管理]《壹百度》 -- 朱光
  18. 基于C语言的随机点名器设计
  19. 计算机视觉领域 CCF重要期刊/国际会议
  20. 创建xml并解析xml_构建,解析和提取XML

热门文章

  1. matlab png,在matlabd中用Python创建.PNG图像
  2. Xcode中常见英文
  3. Simulink仿真传函必看——传递函数大集合(传函状态空间零极点模块)
  4. 【1077】Kuchiguse (20 分)
  5. 娱乐机器人行业:兴于教育,困于教育
  6. 对SEO网站优化使用技巧的总结
  7. 一个网站优化seo的年终工作总结
  8. 搭建STM32CubeMX环境并实现LED流水灯
  9. 程序员:开始编程生涯的5个建议
  10. 专题一:解读直播行业黑产及其产业链(上)