jjzjj

Python读取NC格式数据绘制水汽通量等值线和和流场

野生的气象小流星 2023-04-05 原文

Python读取NC格式数据绘制水汽通量等值线和风场


一、知识点

计算水汽通量,用到了metpy包,是一个地球科学计算包,内置了很多气象用到的计算函数

小知识点:
1.用湿度计算比湿
2.单位的使用
3.常量的使用,这里涉及了重力加速度g

二、代码拆分

导入包

#处理数据的包
import xarray as xr
import numpy as np
#画图的包
import matplotlib.pyplot as plt
#地图的包
import cartopy.crs as ccrs
import my_class                   #一个自己写的画地图的py文件
#科学计算的包
from metpy.units import units      #里面是单位
import metpy.constants          #里面是常数
import metpy.calc                #里面有各种计算函数

读取数据

ds = xr.open_dataset('download_201306.nc')#用xarray读取NC数据
lat = ds.latitude#读取维度
lon = ds.longitude#读取经度
time = ds.time#读取时间
u = ds['u']#风场U分量
v = ds['v']#风场V分量
tem = ds['t']- 273.15#读取温度,转化为摄氏度
rh = ds['r']#读取湿度

注意:这里读取的数据是全部的格点数据,但是我们画图用不了这么多,所以对数据做分割。只需要一部分

数据筛选分割

#设置经纬度范围
lat_range = lat[(lat>=22) & (lat<=33)]
lon_range = lon[(lon>=106) & (lon<=124)]
#筛选数据(经纬度,时间)
u_region = u.sel(longitude=lon_range, latitude=lat_range,time = '2013-06-28T00:00:00.000000000')
v_region = v.sel(longitude=lon_range, latitude=lat_range,time = '2013-06-28T00:00:00.000000000')
tem_region = tem.sel(longitude=lon_range, latitude=lat_range,time = '2013-06-28T00:00:00.000000000')
rh_region = rh.sel(longitude=lon_range, latitude=lat_range,time = '2013-06-28T00:00:00.000000000')

上面获得了世界时2013年6月28日00时的UV风场、温度、湿度
这里解释一下,作者下载的在分析资料里没有分层的数据,只下载了850hPa一层数据,所以不需要设置高度。

数据计算

#给温度赋予单位摄氏度,正真意义上的摄氏度,metpy有单位体系
tem_region = tem_region * units.degC
#气压赋予hPa
pressure = 850 * units.hPa
#用相对湿度和温度计算露点,函数名字就是字面意思
dewpoint = metpy.calc.dewpoint_from_relative_humidity(tem_region, rh_region)
#用露点和气压算比湿,函数名字就是字面意思,因为计算结果是kg数值,乘以1000变成克
specific_humidity = metpy.calc.specific_humidity_from_dewpoint(pressure, dewpoint)*1000
#计算两个方向上的水汽通量,公式就是  速度*比湿/重力加速度
qu = u_region * specific_humidity / metpy.constants.g
qv = v_region * specific_humidity / metpy.constants.g
#和风速一样,勾股定理就得到了水汽通量的分布数值,为啥这么麻烦呢,因为UV分量一会儿还要画箭头
a = np.sqrt(qu * qu + qv*qv)

这里的知识点:
1.温度和气压赋予单位,因为metpy的计算是有单位体系的
2.利用metpy.calc的内置函数计算物理量
dewpoint_from_relative_humidity:露点_from_相对湿度,参数是温度和湿度
specific_humidity_from_dewpoint:比湿_from_露点,参数是气压和露点。
3.利用水汽通量公式:速度*比湿/重力加速度计算水汽通量的UV分量。

画图设置

#画布
fig = plt.figure(figsize=(9,6))
#子图
ax = fig.add_subplot(111,projection = ccrs.PlateCarree())
ax.set_extent([106, 124, 22, 33])
ax.set_xticks(np.arange(106,125,2),crs=ccrs.PlateCarree())
ax.set_yticks(np.arange(22,34,1),crs=ccrs.PlateCarree())
xticks_str = ['106', '108', '110', '112', '114', '116', '118','120', '122', '124°E']
ax.set_xticklabels(xticks_str,fontsize = 11)
yticks_str = ['22   ','23    ','24    ','25    ','26    ','27    ','28    ','29    ','30    ','31    ','32    ','33°N']
ax.set_yticklabels(yticks_str,fontsize = 11)
my_class.readshapefile('bou2_4l.shp',linewidth=1,ax=ax)

画图设置这里就不多讲了,就是弄个画布、弄个子图,设置一下XY轴,加载个地图。

画图

#画水汽通量等值线
ct=ax.contour(lon_range,lat_range,a,8,colors='k',linewidths=1,levels=range(0,28,2))
ax.clabel(ct,inline=True,fontsize=10,fmt='%.0f')
#下面画箭头
#获得XY矩阵格式坐标,这里对纬度上的格点进行了处理,降尺度,从0.25变成了1,其实就是间隔4取值,目的是因为箭头太密影响效果
h1 = ax.quiver(lon_range[::4],lat_range[::4],qu[::4,::4],qv[::4,::4],     #X,Y,U,V 确定位置和对应的风速
                width = 0.002, #箭杆箭身宽度
                scale = 700, # 箭杆长度,参数scale越小箭头越长
                pivot = 'tail'#箭头的其实位置,这里表示从点起,还有点在中心的‘mid’
                )

#画出风场,和箭头箭轴后,得说明 箭轴长度与风速的对应关系
#调用quiver可以生成 参考箭头 + label。
ax.quiverkey(h1,                      #传入quiver句柄
              X=0.8, Y = -0.07,       #确定 label 所在位置,都限制在[0,1]之间
              U = 20,                    #参考箭头长度 表示20。
              angle = 0,            #参考箭头摆放角度。默认为0,即水平摆放
             label='20',        #箭头的补充:label的内容  +
             labelpos='S',          #label在参考箭头的哪个方向; S表示南边
             color = 'k',labelcolor = 'k', #箭头颜色 + label的颜色
             )

这里画了一个等值线,画了一个水汽通量的方向场,其实就是画风场的方法。

出图

plt.show()

三、完整代码

这里的完整代码是两张图,包含了一个循环,就是把两个时次的图放在一起。

'''
知识点:计算水汽通量,用到了metpy包,是一个地球科学计算包,内置了很多气象用到的计算函数
小知识点:1.用湿度计算比湿
          2.单位的使用
          3.常量的使用,这里涉及了重力加速度g
'''
#处理数据的包
import xarray as xr
import numpy as np
#画图的包
import matplotlib.pyplot as plt
#地图的包
import cartopy.crs as ccrs
import my_class
#科学计算的包
from metpy.units import units      #里面是单位
import metpy.constants          #里面是常数
import metpy.calc                #里面有各种计算函数



#循环的东西这里就不讲解了
ds = xr.open_dataset('download_201306.nc')
lat = ds.latitude
lon = ds.longitude
time = ds.time
u = ds['u']
v = ds['v']
tem = ds['t']- 273.15#温度变成摄氏度
rh = ds['r']#湿度


lat_range = lat[(lat>=22) & (lat<=33)]
lon_range = lon[(lon>=106) & (lon<=124)]
fig = plt.figure(figsize=(18,9))

#设置2个子图,并且放到列表里面,方便循环的时候用
plt.subplots_adjust(left=0.07, right=0.90, top=0.95, bottom=0.05,wspace=0.2,hspace=0.1)
ax_a = fig.add_subplot(1,2,1,projection = ccrs.PlateCarree())
ax_b = fig.add_subplot(1,2,2,projection = ccrs.PlateCarree())


ax_list = [ax_a,ax_b]
ab = ['(a)','(b)']#图右上角的ab
i = 0#循环变量

for time_i in time:
    #风U
    u_region = u.sel(longitude=lon_range, latitude=lat_range,time = time_i)
    #风V
    v_region = v.sel(longitude=lon_range, latitude=lat_range,time = time_i)
    #温度
    tem_region = tem.sel(longitude=lon_range, latitude=lat_range,time = time_i)
    #湿度
    rh_region = rh.sel(longitude=lon_range, latitude=lat_range,time = time_i)
    #给温度赋予单位摄氏度,正真意义上的摄氏度,metpy有单位体系
    tem_region = tem_region * units.degC
    #气压赋予hPa
    pressure = 850 * units.hPa
    #用相对湿度和温度计算露点,函数名字就是字面意思
    dewpoint = metpy.calc.dewpoint_from_relative_humidity(tem_region, rh_region)
    #用露点和气压算比湿,函数名字就是字面意思,因为计算结果是kg数值,乘以1000变成克
    specific_humidity = metpy.calc.specific_humidity_from_dewpoint(pressure, dewpoint)*1000
    #计算两个方向上的水汽通量,公式就是  速度*比湿/重力加速度
    qu = u_region * specific_humidity / metpy.constants.g
    qv = v_region * specific_humidity / metpy.constants.g
    #和风速一样,勾股定理就得到了水汽通量的分布数值,为啥这么麻烦呢,因为UV分量一会儿还要画箭头
    a = np.sqrt(qu * qu + qv*qv)



    ax_list[i].set_extent([106, 124, 22, 33])
    ax_list[i].set_xticks(np.arange(106,125,2),crs=ccrs.PlateCarree())
    ax_list[i].set_yticks(np.arange(22,34,1),crs=ccrs.PlateCarree())
    xticks_str = ['106', '108', '110', '112', '114', '116', '118','120', '122', '124°E']
    ax_list[i].set_xticklabels(xticks_str,fontsize = 11)
    yticks_str = ['22    ','23    ','24    ','25    ','26    ','27    ','28    ','29    ','30    ','31    ','32    ','33°N']
    ax_list[i].set_yticklabels(yticks_str,fontsize = 11)
    my_class.readshapefile('bou2_4l.shp',linewidth=1,ax=ax_list[i])


    #画等值线
    ct=ax_list[i].contour(lon_range,lat_range,a,8,colors='k',linewidths=1,levels=range(0,28,2))
    ax_list[i].clabel(ct,inline=True,fontsize=10,fmt='%.0f')


    #下面画箭头
    #获得XY矩阵格式坐标,这里对纬度上的格点进行了处理,降尺度,从0.25变成了1,其实就是间隔4取值,目的是因为箭头太密影响效果
    h1 = ax_list[i].quiver(lon_range[::4],lat_range[::4],qu[::4,::4],qv[::4,::4],     #X,Y,U,V 确定位置和对应的风速
                    width = 0.002, #箭杆箭身宽度
                    scale = 700, # 箭杆长度,参数scale越小箭头越长
                    pivot = 'tail'#箭头的其实位置,这里表示从点起,还有点在中心的‘mid’
                    )

    #画出风场,和箭头箭轴后,得说明 箭轴长度与风速的对应关系
    #调用quiver可以生成 参考箭头 + label。
    ax_list[i].quiverkey(h1,                      #传入quiver句柄
                  X=0.8, Y = -0.07,       #确定 label 所在位置,都限制在[0,1]之间
                  U = 20,                    #参考箭头长度 表示风速为5m/s。
                  angle = 0,            #参考箭头摆放角度。默认为0,即水平摆放
                 label='20',        #箭头的补充:label的内容  +
                 labelpos='S',          #label在参考箭头的哪个方向; S表示南边
                 color = 'k',labelcolor = 'k', #箭头颜色 + label的颜色
                 )

    #写abcd
    ax_list[i].text(0.05, 0.95, ab[i],transform=ax_list[i].transAxes, fontsize=11)

    #一次循环结束 i+1
    i += 1


plt.show()

有关Python读取NC格式数据绘制水汽通量等值线和和流场的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  6. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  7. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  8. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  9. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  10. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

随机推荐