python画风羽及风羽定义

basemap使用手册:链接:https://pan.baidu.com/s/1CUgQcsuYMbJAdCuij4WsLQ 
提取码:aw16 

如果想用箭头画风场,请看另一篇python matplotlib quiver——画箭头、风场

首先说下风羽是怎么回事:

当我们表示风向的时候,我们当然可以用简单的箭头指示即可,但箭头不能表示出风速的信息。为了简单而有效的表达出风的大小和方向,于是就创造了风羽——一个相对紧凑的图形(当然也许可以创造出更好地表示方法,但风羽先被广泛接受)。怎么来解读一个风羽呢?参看下图:

python画风羽及风羽定义_第1张图片

上图中长杆代表风向,短杆和小旗子代表风速。

短杆的朝向:设想你站在风速羽长杆上,末端是短杆所在一侧,你面对短杆,那么北半球画风羽,短杆在你的右侧,南半球画风羽,短杆则画在左侧,这是一种惯例。

python画风羽及风羽定义_第2张图片

国外:长杆代表风向,短杆代表风速,每个短杆为10knots,如果是半个短杆,则为5knots(1knot=1节=0.514m/s)
国内:长杆代表风向,短杆代表风速,每个短杆为4m/s,如果是半个短杆,则为2m/s。(1m/s=1.94knots)
(好吧,我认为这个换算单位很烦,英美仍然用着他们的英里什么的,在风速这里实际上是用的海里,海里的话当然为了当时的方便,现在沿用这些,感觉没必要,公制万岁!)

那测量风向的时候(我得到的数据就是一个角度),记录的就是风的来向,0°应该是正北来风,90°正东来风,以此类推。

参考:

https://baike.baidu.com/item/%E9%A3%8E%E9%80%9F%E7%BE%BD/5018668

http://weather.rap.ucar.edu/info/about_windbarb.html

其次说说python中怎么画风羽:

参考:

https://matplotlib.org/api/_as_gen/matplotlib.pyplot.barbs.html

https://www.cnblogs.com/kallan/p/6279932.html

风羽函数:

barb(X, Y, U, V,, **kw)

barbs的参数:

X:风场数据X坐标
Y:风场数据Y坐标
U:风的水平方向分量
V:风的垂直方向分量

这里水平分量和垂直分量值得商榷,就是你的角度数据所在坐标系与函数中的不一样,有时会产生结果与你的预期不正确的情况。

python画风羽及风羽定义_第3张图片

实操

首先看以下代码:

import matplotlib.pyplot as plt
import math

ax = plt.subplot(1,1,1)
wind = [100,100,100,100]
angle = [45, 135, 225, 315]
a = range(1,5)
b = range(1,5)

ver = [spd*math.sin(math.radians(agl)) for spd,agl in zip(wind, angle)]  #vertical value
hriz = [spd*math.cos(math.radians(agl)) for spd,agl in zip(wind, angle)]  #horizontal value
ax.barbs(a, b, ver, hriz)
plt.show()

得到如下结果:

python画风羽及风羽定义_第4张图片

这不太对,我说结果不太对,是方向的问题。根据前面对风羽的介绍,45°那里的结果是西南来风,但是45°应该是东北来风啊,所以说他错了,另外几个亦复如是。我的风向是罗盘坐标系下的角度,就是上图fig a的坐标系,函数的坐标系我没找到。改的结果也很简单,试了一下,就是将水平和垂直分量的值变成其相反数,得到预期结果:

import matplotlib.pyplot as plt
import math

ax = plt.subplot(1,1,1)
wind = [100,100,100,100]
angle = [45, 135, 225, 315]
a = range(1,5)
b = range(1,5)

ver = [-spd*math.sin(math.radians(agl)) for spd,agl in zip(wind, angle)]  #vertical value
hriz = [-spd*math.cos(math.radians(agl)) for spd,agl in zip(wind, angle)]  #horizontal value
ax.barbs(a, b, ver, hriz)
plt.show()

结果如下:

python画风羽及风羽定义_第5张图片

此外,如果您想在地图上画出风羽,借助basemap,实现代码如下:

import matplotlib.pyplot as plt
import math
from mpl_toolkits.basemap import Basemap

ax = plt.gca()
wind = [100,100,100,100]
angle = [45, 135, 225, 315]
a = [113.9, 114.1, 114.3, 114.5]
b = [22.5, 22.6, 22.7, 22.8]
m = Basemap(llcrnrlon=113.7, llcrnrlat=22.35, urcrnrlon=114.7, urcrnrlat=22.9,\
            rsphere=(6378137.00,6356752.3142),\
            resolution='l', area_thresh=1000., projection='lcc', lat_1=22.5, lat_0=22.5, lon_0=114,ax=ax)
#下面两行是读取地图中的shape文件,即轮廓图
m.readshapefile(r'G:\深圳季风研究\gadm36_HKG_shp\gadm36_HKG_0', 'states',color='grey') #HongKong
m.readshapefile(r'G:\深圳季风研究\gadm36_CHN_shp\gadm36_CHN_2', 'states',color='grey') #Mainland in given lon and lat
a1,b1=m(*(a,b))  #这里将经纬度坐标转化成像素点坐标

ver = [-spd*math.sin(math.radians(agl)) for spd,agl in zip(wind, angle)]
hriz = [-spd*math.cos(math.radians(agl)) for spd,agl in zip(wind, angle)]

ax.barbs(a1,b1,ver,hriz)
plt.show()

结果如下:

python画风羽及风羽定义_第6张图片

注意:

关于风羽的风速,ax.barbs()中当风速在(0,2.5)时,认为无风画一圆圈,在(2.5,7.5)为一短杆。

关于颜色等问题,可以自行参考官方文档或百度之

你可能感兴趣的:(basemap,地图,Python,matplotlib,风羽,python)