Python气象数据处理与绘图(11):矢量箭头图(风场,通量场)

最近在计算波作用通量,正好就画到了矢量箭头图,画的过程中发现还是有很多细节需要注意的,那就直接进入正题吧。
首先,矢量箭头图是分为两种的,一种类似我们常见的风场(左图),另一种则是特殊的流场,也就是流线图(右图),这两张都是画的Plumb通量,显然对于波通量来说还是箭头好一些。


矢量箭头

对于左图和右图来说分别使用的画图函数为:

quiver([X, Y], U, V, [C], **kw)

streamplot([X, Y], U, V, [C], **kw)

我整理了相应的参数:

1. quiver

X: 数组,

为X坐标,通常为我们的经度lon

Y:

为Y坐标,通常为我们的纬度lat

U:
纬向风分量,二维数组
V:
 经向风分量,二维数组
C:
  箭头颜色数组,可为一种颜色,也可为颜色数组
units(单位): [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ]

箭头尺寸(除长度外)以此单位的倍数计算——即是说选定单位后,箭头尺寸即是此单位的倍数
‘width’或’height’:轴(axis)的宽度或高度
‘dots’或’inches’:像素或英寸,基于图的dpi
‘x’, ‘y’或‘xy’:分别是X、Y或X2+Y2的数据单位(data units)
箭头依单位不同而不同。对于’x’或’y’,箭头会随着其一的增大(zoom in)而增大;对于其他单位,箭头的大小与缩放状态(zoom state)无关。对于’width’或’height’,当窗口重置时,箭头的大小会随着轴(axes)的宽度和高度的增大而增大

angles: [‘uv’ | ‘xy’]

用于决定箭头角度的方法,默认是’uv’
‘uv’:箭头的纵横比(axis aspect ratio)为1,所以若U==V,则绘图上箭头的方向与水平轴逆时针呈45度(正向右)。
‘xy’: 箭头从(x,y)指向(x + u,y + v)。例如,使用它来绘制渐变场(gradient field)。
或者,可以将任意角度指定为以水平轴逆时针方向的度数值的数组。
注意:反转数据轴将相应地仅使用angles='xy'反转箭头。

scale :

每个箭头长度单位的数据单位数量,例如,每个绘图宽度m / s;参数scale越小箭头越长。默认是None
若是None,一个简单的自动缩放算法将被采用,基于平均矢量长度和适量的数量。箭头长度单位由scale_units参数给出。

scale_units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ]

如果关键字参数scale是None,那么箭头长度单位默认是None
例如:scale_units是’inches’,scale是2.0,(u,v)=(1,0),那么矢量将会是0.5英寸长。
如果scale_units是’width/height’,那么矢量长度是轴’width/height’的半长
如果scale_units是’x’那么矢量是x轴单位的0.5倍。要在x-y平面上画矢量,使得u和v与x和y有相同的单位,则应另angles=’xy’, scale_units’xy’, scale=1.

width : scalar(标量), optional

箭头杆(shaft)的宽度,以箭头单位衡量。常用的初始值是0.005倍的画的宽度

headwidth :

头部宽度相对于箭杆宽度的倍数,默认是3倍

headlength :

轴交叉处的头部长度,默认是4.5

minshaft :

箭头比例的长度,以头部长度为单位。

minlength :

最小长度为轴宽的倍数;如果箭头长度小于此值,则绘制该直径的点(六边形)。

pivot : [ 'tail' | 'mid' | 'middle' | 'tip' ], optional

箭头的基点,比如说选择mid,那个箭头中间位置就是所在坐标点位置。
老实说,关于units,scale,和scale_units的设置十分复杂,画图时可先均不设置,看看默认效果,然后逐渐调整。通常只调整scale即可,另外两项除非必要,均可不设置。

2. streamplot

略过相同部分

density : float
控制流线的闭合度。当密度为1时,将域划分为30x30网格。密度线性缩放此网格。网格中的每个单元格最多只能有一条横贯流线。对于每个方向上的不同密度,使用一个元组(密度x,密度y)。

linewidth : float or 2D array
流线的宽度。使用二维数组,可以在网格上改变线宽。数组的形状必须与u和v相同。

color:matplotlib颜色代码或二维数组
流线型的颜色。如果给定一个数组,则使用cmap和norm将其值转换为颜色。数组的形状必须与u和v相同。

cmap:颜色映射
用于绘制流线和箭头的彩色地图。这只在颜色是数组时使用。

norm:
规格化用于将亮度数据缩放到0,1的对象。如果没有,则拉伸(最小,最大)到(0,1)。这只在颜色是数组时使用。

arrowsize:float
箭头大小的比例因子。

arrowstyle:str
箭头样式。见https://matplotlib.org/api/_as_gen/matplotlib.patches.FancyArrowPatch.html#matplotlib.patches.FancyArrowPatch

minlength:浮动
轴线坐标中流线的最小长度。

start_points :
数据坐标中流线起点的坐标(与x和y数组的坐标相同)。

maxlength:浮点
轴线坐标中流线的最大长度。

integration_direction:{'forward','backward','both'}
将流线向前、向后或双向整合。默认值为“both”。
以上便是常用参数,仍有一些参数是可以使用的,比如说zorder(图层顺序),transform(坐标转换)等等。需要注意的是,当我们在地图投影上叠加风场时,需要设置transform=ccrs.PlateCarree() 来将坐标转换为圆柱地图投影坐标,该参数调用了cartopy库的函数,具体使用可参考我先前发布的文章,有关于地图投影的详细描写。
那么,再回到我们最开始展示的那张图,我给出该图的部分代码以供参考。

#以下四行为地图投影以及坐标轴的设置,具体参考先前发布的文章
proj = ccrs.PlateCarree(central_longitude=50)
leftlon, rightlon, lowerlat, upperlat = (0,180,0,90)
img_extent = [leftlon, rightlon, lowerlat, upperlat]
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
#创建画布
fig7 = plt.figure(figsize=(12,8))
#创建地图投影子图
f7_ax1 = fig7.add_axes([0.1, 0.1, 0.6, 0.6],projection = proj)
#地图相关设置,包括边界,河流,海岸线,坐标的经纬度显示
f7_ax1.set_extent([leftlon, rightlon, lowerlat, upperlat], crs=ccrs.PlateCarree())
f7_ax1.add_feature(cfeature.COASTLINE.with_scale('50m'))
f7_ax1.add_feature(cfeature.LAKES, alpha=0.5)
f7_ax1.set_xticks(np.arange(leftlon,rightlon+10,10), crs=ccrs.PlateCarree())
f7_ax1.set_yticks(np.arange(lowerlat,upperlat+10,10), crs=ccrs.PlateCarree())
f7_ax1.xaxis.set_major_formatter(lon_formatter)
f7_ax1.yaxis.set_major_formatter(lat_formatter)
f7_ax1.set_title('(a)  quiver',loc='left')
#因为是波作用通量,首先画扰动流函数
cf=f7_ax1.contourf(lon,lat,streamf_mean/1e5,cmap='RdBu_r',extend='both',levels=np.arange(-16,18,2),transform=ccrs.PlateCarree())
c=f7_ax1.contour(lon,lat,streamf_mean/1e5,colors='black',linewidths=0.5,levels=np.arange(-16,18,2),transform=ccrs.PlateCarree())
#画矢量箭头核心代码在这里,::2表示每隔2个点画箭头,不然会太密集,记得在投影坐标上画时一定要设置transform
Q = f7_ax1.quiver(lon[::2], lat[::2], px_mean[::2,::2], py_mean[::2,::2],pivot='mid',width=0.0018,scale=10,headwidth=4,transform=ccrs.PlateCarree())     
#添加色标
position=fig7.add_axes([0.57, 0.08, 0.35, 0.025])
fig7.colorbar(cf,cax=position,orientation='horizontal',format='%d',)

右半图的代码就不展示了,唯一区别就是quiver变成了streamplot,我没有过多修改。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容