失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > python气象数据可视化学习笔记7——利用cartopy+cnmaps和ERA5数据绘制填色图并对中国地区白化

python气象数据可视化学习笔记7——利用cartopy+cnmaps和ERA5数据绘制填色图并对中国地区白化

时间:2022-08-22 09:21:49

相关推荐

python气象数据可视化学习笔记7——利用cartopy+cnmaps和ERA5数据绘制填色图并对中国地区白化

文章目录

1. 效果图2. 绘制基于中国地区的填色图(大地图)3. 添加南海小地图4. 读取数据并传入绘图函数5. 代码完整版

1. 效果图

前序博文cnmaps填色图介绍了cnmaps在线地图库如何绘制省级边界和白化,cartopy白化介绍了如何用cartopy白化中国地区(包含南海小地图和九段线),这篇博文可以说是两者的结合,即用cnmaps+cartopy白化中国地区并添加南海小地图,是更为方便简洁的中国地区白化方法。

2. 绘制基于中国地区的填色图(大地图)

这块主要绘制的是填色的中国大地区,并白化,和前序博文cnmaps填色图的思路基本一致,即:

利用get_adm_maps获取地图边界ax.contourf绘制填色图clip_contours_by_map 对中国地区进行白化draw_maps绘制中国地图边界ax.coastlines() 绘制海岸线ax.set_extent确定大地图显示的经纬度范围设置标题、添加经纬度和colorbar

值得注意的是,如果要添加南海九段线,绘制地图的时候要用map的返回值,如果用map_oneline,则没有九段线,只有南海诸岛。而对于白化来说,一定要使用map的地图返回,不然会报错,所以,代码里地图的返回值用了两种方式。本人还没发现更好的解决这个问题的办法,如果其他同学发现了,欢迎在评论区交流。

def map_plot(fig,ax,lat,lon,data, is_mask, is_province_boundary,title):# 获取地图big_map = get_adm_maps(country='中华人民共和国', level='国') #包含南海九段线,用于地图绘制big_map_oneline = get_adm_maps(country='中华人民共和国', level='国', record='first', only_polygon=True) #用于白化#绘制填色图cf = ax.contourf(lon, lat,data, cmap=plt.cm.jet,levels=np.linspace(-12, 30, 43),transform=ccrs.PlateCarree())#设置是否白化,白化必须基于一条边界(jingjinji2)if is_mask:clip_contours_by_map(cf, big_map_oneline)#绘制地图draw_maps(big_map,linewidth=1.2, color='k') #仅绘制所有省份的一条边界#添加海岸线ax.coastlines()#设置显示区域ax.set_extent([70,140,15,55], crs=ccrs.PlateCarree())#设置标题ax.set_title(title)#添加经纬度格网gl=ax.gridlines(draw_labels=True,linestyle=":",linewidth=0.1 ,x_inline=False, y_inline=False,color='k')gl.top_labels=False #关闭上部经纬标签 gl.right_labels=False#关闭右边经纬标签 gl.rotate_labels=None#关闭兰伯特经纬标签旋转 gl.xformatter = LONGITUDE_FORMATTER #使横坐标转化为经纬度格式 gl.yformatter = LATITUDE_FORMATTER #添加coloarbarfig.colorbar(cf,ax=ax, shrink=0.9, extendfrac='auto',extendrect=True,location='bottom',fraction=0.05, pad=0.08)

3. 添加南海小地图

添加南海小地图就是图中图的概念,最关键的有以下几点:

确定南海小地图的经纬度范围,即box_nanhai生成南海小地图的ax_nanhai = fig.add_axes(pos,projection = ccrs.PlateCarree()) ,其中pos为南海小地图在fig中的位置和大小按照大地图的方法,用ax_nanhai绘制填色图并白化

这里需要注意的是,绘制南海填色图时,lat, lon, data一定要用南海小地图范围内的数据,不要用全部大地图的数据,不然会出现两个大地图在同一图中。

#----------添加南海小地图------------------def add_nanhai (ax, pos, lat, lon, data):#--------------右下角添加南海地图------------------------------------------lon1, lon2, lat1, lat2 = 103, 125, 2, 25box_nanhai=[lon1, lon2, lat1, lat2] #南海小地图的经纬度位置ax_nanhai = fig.add_axes(pos,projection = ccrs.PlateCarree()) #定义ax_nanhai# #重新选择data数据,削减掉box_nanhai以外的数据,不然会把整个大地图填色再添加到图中# lon_new = lon[]# 重复大地图的画图步骤nanhai = get_adm_maps(country='中华人民共和国', level='国') #包含南海九段线,用于地图绘制nanhai_oneline = get_adm_maps(country='中华人民共和国', level='国', record='first', only_polygon=True) #用于白化ax_nanhai.set_extent(box_nanhai, crs=ccrs.PlateCarree())cf = ax_nanhai.contourf(lon.loc[lon1:lon2], lat.loc[lat1:lat2],data.loc[lat1:lat2, lon1:lon2], cmap=plt.cm.jet,levels=np.linspace(-12, 30, 43),transform=ccrs.PlateCarree())clip_contours_by_map(cf, nanhai_oneline)draw_maps(nanhai,linewidth=0.8, color='k')ax_nanhai.coastlines()

4. 读取数据并传入绘图函数

读取数据:使用的是ERA5的2m温度日均值(nc数据),并用xarray读取并做月平均,最后得到的temp是二维数组(lat, lon),比较简单,不用介绍了。

# read datadata_path = "D:/ERA5/era5_for_o3/download_daily_mean_2m_temperature__04.nc"ds = xr.open_dataset(data_path)temp = ds['t2m'].mean('time')-273.17 #求月均值,并换算为百帕lat, lon = ds['lat'], ds['lon']

定义画布并将数据传入绘图函数

将fig, ax, lat, lon, data等先后传入大地图函数map_plot和南海小地图函数add_nanhai中,大功告成啦,也可用此函数绘制多个子图。

# 定义画布proj = ccrs.PlateCarree()fig = plt.figure(figsize=(6, 6))#调入参数,画图ax1 = fig.add_subplot(1,1,1, projection=proj)map_plot(fig, ax1, lat, lon, temp, True, True, 'T2 in April ') #绘制大地图pos1 = [0.78, 0.213, 0.12, 0.12] #南海小地图位置和长宽,根据画布自己调试add_nanhai(ax1,pos1,lat,lon,temp) #添加南海小地图plt.savefig('t2.jpg')

5. 代码完整版

# %%import xarray as xrimport numpy as np import matplotlib.pyplot as pltimport matplotlib as mplimport cartopy.crs as ccrsfrom cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTERfrom cnmaps import get_adm_maps, draw_maps,clip_contours_by_map, draw_mapmpl.rcParams["font.size"] = 13# %%#----------------绘制大地图------------------------------def map_plot(fig,ax,lat,lon,data, is_mask, is_province_boundary,title):# 获取地图big_map = get_adm_maps(country='中华人民共和国', level='国') #包含南海九段线,用于地图绘制map_oneline = get_adm_maps(country='中华人民共和国', level='国', record='first', only_polygon=True) #用于白化#绘制填色图cf = ax.contourf(lon, lat,data, cmap=plt.cm.jet,levels=np.linspace(-12, 30, 43),transform=ccrs.PlateCarree())#设置是否白化,白化必须基于一条边界(jingjinji2)if is_mask:clip_contours_by_map(cf, big_map_oneline)#绘制地图draw_maps(big_map,linewidth=1.2, color='k') #仅绘制所有省份的一条边界#添加海岸线ax.coastlines()#设置显示区域ax.set_extent([70,140,15,55], crs=ccrs.PlateCarree())#设置标题ax.set_title(title)#添加经纬度格网gl=ax.gridlines(draw_labels=True,linestyle=":",linewidth=0.1 ,x_inline=False, y_inline=False,color='k')gl.top_labels=False #关闭上部经纬标签 gl.right_labels=False#关闭右边经纬标签 gl.rotate_labels=None#关闭兰伯特经纬标签旋转 gl.xformatter = LONGITUDE_FORMATTER #使横坐标转化为经纬度格式 gl.yformatter = LATITUDE_FORMATTER #添加coloarbarfig.colorbar(cf,ax=ax, shrink=0.9, extendfrac='auto',extendrect=True,location='bottom',fraction=0.05, pad=0.08) # %%#----------添加南海小地图------------------def add_nanhai (ax, pos, lat, lon, data):#--------------右下角添加南海地图------------------------------------------lon1, lon2, lat1, lat2 = 103, 125, 2, 25box_nanhai=[lon1, lon2, lat1, lat2] #南海小地图的经纬度位置ax_nanhai = fig.add_axes(pos,projection = ccrs.PlateCarree()) #定义ax_nanhai# #重新选择data数据,削减掉box_nanhai以外的数据,不然会把整个大地图填色再添加到图中# lon_new = lon[]# 重复大地图的画图步骤nanhai = get_adm_maps(country='中华人民共和国', level='国') #包含南海九段线,用于地图绘制nanhai_oneline = get_adm_maps(country='中华人民共和国', level='国', record='first', only_polygon=True) #用于白化ax_nanhai.set_extent(box_nanhai, crs=ccrs.PlateCarree())cf = ax_nanhai.contourf(lon.loc[lon1:lon2], lat.loc[lat1:lat2],data.loc[lat1:lat2, lon1:lon2], cmap=plt.cm.jet,levels=np.linspace(-12, 30, 43),transform=ccrs.PlateCarree())clip_contours_by_map(cf, nanhai_oneline)draw_maps(nanhai,linewidth=0.8, color='k')ax_nanhai.coastlines()# %%# read datadata_path = "D:/ERA5/era5_for_o3/download_daily_mean_2m_temperature__04.nc"ds = xr.open_dataset(data_path)temp = ds['t2m'].mean('time')-273.17 #求月均值,并换算为百帕lat, lon = ds['lat'], ds['lon']# %%# 定义画布proj = ccrs.PlateCarree()fig = plt.figure(figsize=(6, 6))#调入参数,画图ax1 = fig.add_subplot(1,1,1, projection=proj)map_plot(fig, ax1, lat, lon, temp, True, True, 'T2 in April ') #绘制大地图pos1 = [0.78, 0.213, 0.12, 0.12] #南海小地图位置和长宽,根据画布自己调试add_nanhai(ax1,pos1,lat,lon,temp) #添加南海小地图plt.savefig('t2.jpg')# %%

如果觉得《python气象数据可视化学习笔记7——利用cartopy+cnmaps和ERA5数据绘制填色图并对中国地区白化》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。