python--循环绘制ERA5风场的空间分布图

简介: 使用python封装绘图函数循环绘制ERA5风场资料的空间分布图

使用python封装绘图函数循环绘制ERA5风场资料的空间分布图



通常,在处理气象海洋资料时,经常会绘制风场的空间分布图进行简单分析,而常常需要连续绘制多天,并将多张子图绘制到同一个图片中,因此这就需要用到循环绘图。


  • 同时考虑到下载的ERA5风场资料的经度排列顺序是-180~180°,这里也简单进行了经度转换,将其转换为0 ~ 360的排列顺序。
  • 根据每个子图的数据,将选取的时间也在循环中加上
  • 考虑到绘制全球的处理时间较久,这里自由选取任意经纬度进行绘制
  • 由于每张子图的填色范围是固定的,所以统一绘制colorbar,至于图片最下端
  • 箭头为风场风量,填色为风速大小


下面附上代码:


# -*- coding: utf-8 -*-
"""
Created on %(date)s
@author: %(jixianpu)s
Email : 211311040008@hhu.edu.cn
introduction : keep learning althongh walk slowly
"""
from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter
import numpy as np
import pandas as pd
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
import matplotlib.pyplot as plt
import xarray as xr
import glob
from scipy import signal
path=r'G:/ERA5_200406/'
str1='uwnd.200406.nc'
str2='vwnd.200406.nc'
# b, a = signal.butter(3, [(2/10)/(1/0.25),(2/3)/(1/0.25)], 'bandpass')
######===================
def make_map(ax, title):
    # set_extent  set crs
    ax.set_extent(box, crs=ccrs.PlateCarree())
    land = cfeature.NaturalEarthFeature('physical',
                                        'land',
                                        scale,
                                        edgecolor='grey', 
                                        facecolor='grey'
                                        ,zorder=2
                                        )
    ax.add_feature(land)  # set land color
    ax.coastlines(scale)  # set coastline resolution
    # set coordinate axis
    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())
    ax.xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label =False))#经度0不加标识
    ax.yaxis.set_major_formatter(LatitudeFormatter())
    # plt.tick_params(labelsize=25)
    ax.set_title(title, fontsize=20, loc='left',pad=12)
    ax.yaxis.set_minor_locator(AutoMinorLocator(5))
    ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    ax.tick_params(which='minor', 
                    direction='out', length=4,width=0.59,
                    right=True, top=True)
    ax.tick_params(which='major', 
                    direction='out', 
                    length=8,
                    width=0.99, 
                    pad=3, 
                    labelsize=10,
                    bottom=True, left=True, right=True, top=True)
    return ax
# # prepare 
box = [100, 180, -30, 0]  
scale = '50m'            
xstep, ystep = 20, 10 
# cmap=plt.get_cmap('RdYlBu_r')#'RdYlBu_r'
# =======================data============================================
day=(np.arange(19,31))
da = xr.open_dataset(path+str1).sortby("latitude", ascending= True)
da2=xr.open_dataset(path+str2).sortby("latitude", ascending= True)
#####################reverse################################################
lon_name = 'longitude'  # whatever name is in the data
da['longitude_adjusted'] = xr.where(da[lon_name] < 0, da[lon_name]%360,\
                      da[lon_name])
da = (
   da
   .swap_dims({lon_name: 'longitude_adjusted'})
   .sel(**{'longitude_adjusted': sorted(da.longitude_adjusted)})
   .drop(lon_name))
da = da.rename({'longitude_adjusted': lon_name})
#####################reverse################################################
lon_name = 'longitude'  # whatever name is in the data
da2['longitude_adjusted'] = xr.where(da2[lon_name] < 0, da2[lon_name]%360,\
                      da2[lon_name])
da2 = (
   da2
   .swap_dims({lon_name: 'longitude_adjusted'})
   .sel(**{'longitude_adjusted': sorted(da2.longitude_adjusted)})
   .drop(lon_name))
da2 = da2.rename({'longitude_adjusted': lon_name})
#####################reverse################################################
fig=plt.figure(figsize=(14,14))
levels=np.arange(0,21,1)
 # wspace 调整水平的
plt.subplots_adjust(hspace=0.1) 
plt.tight_layout()
count=0
for i  in day:
    count+=1
    print(count)
    tim_s='2004-06-'+str(i)+'-00'
# longitude=slice(0,181)
    u=da.u.sel(level=slice(850,850),latitude=slice(-30,0),longitude=slice(100,180),time=slice(tim_s,tim_s))[0][0]
    v=da2.v.sel(level=slice(850,850),latitude=slice(-30,0),longitude=slice(100,180),time=slice(tim_s,tim_s))[0][0]
    w=np.sqrt(u*u+v*v)
    lon=u.longitude.data
    lat=u.latitude.data
    x,y=np.meshgrid(lon,lat)
    t=u.time
    step=10
    # =======================plot============================================
    ax=fig.add_subplot(4,3,count,projection=ccrs.PlateCarree(central_longitude=180))
    make_map(ax,pd.to_datetime(t.data).strftime('%Y_%m_%d_%H:00'))
    ax.quiver(x[::step,::step],y[::step,::step],u.data[::step,::step],v.data[::step,::step],pivot='mid',\
        width=0.003,scale=200,headlength=4,headwidth=4,
        transform=ccrs.PlateCarree(),color='k',angles='xy'
        ,zorder=2)
    # ax.set_aspect('auto')
    plot=ax.contourf(x,y,w,transform=ccrs.PlateCarree(),extend='both',levels=levels
                  ,zorder=1)
# cb=fig.colorbar(plot,ax=ax,shrink=0.8,pad=0.05,aspect=15)
# cb.ax.tick_params(labelsize=20)
# cb.ax.set_title('$°C$',fontsize=20,loc='right')
# if count==6:
#     break
ax3=fig.add_axes([0.25,0.1,0.5,0.015])  # 0.25控制距离左边的距离,0.01控制距离下面的距离,最后两位控制color的长度和厚度
cb=fig.colorbar(plot,cax=ax3,shrink=0.9,pad=0.04,ticks=[0,5,10,15,20],aspect=15,orientation='horizontal')
cb.ax.tick_params(labelsize=10)
cb.ax.set_title('$m/s$',fontsize=15)
plt.show()
# fig.savefig('wind_850hpa-2004-06-19_30.png',format='png',dpi=100)


绘制结果如下图所示:


d585f665ec5243978724d2ff7f79614b.png


相关文章
|
20天前
|
索引 Python
Python循环怎么给enumerate和for做对比
**Python中的`for`循环遍历集合,而`enumerate`函数在迭代时提供元素的索引。
|
10天前
|
设计模式 开发者 Python
Python中循环依赖问题及其解决方案
循环依赖是 Python 开发中需要特别注意的问题。通过重新设计模块结构、延迟导入、依赖注入、利用 Python 的动态特性以及代码重构等方法,可以有效地解决循环依赖问题。这些策略不仅有助于提高代码的可维护性和可读性,还能避免潜在的运行时错误。在实际开发中,开发者应该根据具体情况选择合适的解决方案。
|
21天前
|
设计模式 算法 Python
Python回调函数中的循环艺术:深入探索for循环的回调应用
Python回调函数中的循环艺术:深入探索for循环的回调应用
12 1
|
26天前
|
Python
Python教程:一文了解Python的条件、循环语句
条件语句(Conditional Statements)是编程中用于根据条件执行特定代码块的结构。在 Python 中,条件语句通常使用 if、elif 和 else 关键字来实现。通过条件语句,程序可以根据不同的条件选择性地执行不同的代码块。 循环语句(Loop Statements)则是一种重复执行特定代码块的结构。在 Python 中,常见的循环语句有 while 循环和 for 循环。循环语句允许程序根据特定的条件或者对一个序列进行迭代,重复执行一段代码,直到满足退出循环的条件为止。
13 1
|
26天前
|
Python
在Python中,`range()`函数生成一个整数序列,用于循环迭代。
【6月更文挑战第19天】`Python`的`range()`函数生成整数序列,用于迭代。它接受`start`(默认0)、`stop`(不包含,右开)和`step`(默认1)参数。在`for`循环中,`range(5)`会输出0到4。若要包含结束值,需将`stop`设为`end+1`,如`range(1, 6)`将输出1到5。
32 1
|
27天前
|
Python
【随手记】python语言的else语句在for、while等循环语句中的运用
【随手记】python语言的else语句在for、while等循环语句中的运用
25 2
|
5天前
|
Python
155. 最小栈 力扣 python 空间换时间 o(1) 腾讯面试题
155. 最小栈 力扣 python 空间换时间 o(1) 腾讯面试题
|
27天前
|
开发者 Python
Python基础第三篇(Python逻辑判断与循环)
Python基础第三篇(Python逻辑判断与循环)
|
1月前
|
存储 网络架构 索引
Python基础教程(第3版)中文版 第5章 条件、循环及其他语句(笔记)
Python基础教程(第3版)中文版 第5章 条件、循环及其他语句(笔记)
|
13天前
|
C++ Python
揭秘!Python高手都在用的数据类型秘籍,列表推导式让你告别繁琐循环
【7月更文挑战第2天】Python的列表推导式是高手必备技巧,它让复杂的循环简化为一行代码,提升代码的可读性和效率。例如,要计算数字列表的平方,传统循环需使用`for`和`append()`,而列表推导式只需`[number ** 2 for number in numbers]`。此外,它还能结合条件表达式,如筛选并平方偶数:`[number ** 2 for number in numbers if number % 2 == 0]`。学会列表推导式,让你的Python代码更优雅、更易维护。