爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 30851|回复: 16

[秀图] matlab m_map工具箱 m_quiver m_vec 矢量箭头 经验分享

[复制链接]

新浪微博达人勋

发表于 2021-2-19 15:37:26 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
m_map工具箱比较老了,但有时候不得不用。说到绘制风矢量箭头,一般都是用m_quiver,但是也有问题
官方文档还提到了m_vec,但是作者偷懒了,就提了一句:详见m_vec.m的代码,全网都只能搜到这句话
那我就做全网详解m_vec第一人。


                               
登录/注册后可看大图



先说结论,m_quiver能满足要求的,尽量别用m_vec


                               
登录/注册后可看大图



目标:绘制200hPa风箭头

  1. clc
  2. clear all
  3. close all
  4. lat=ncread('ERA5_200hPa.nc','latitude');
  5. lon=ncread('ERA5_200hPa.nc','longitude');
  6. t=ncread('ERA5_200hPa.nc','time');
  7. u10=ncread('ERA5_200hPa.nc','u');
  8. v10=ncread('ERA5_200hPa.nc','v');
  9. timenum=10;%选取某个特定时次
  10. [long,latt]=meshgrid(double(lon),double(lat));
  11. u=squeeze((u10(:,:,timenum)))';
  12. v=squeeze((v10(:,:,timenum)))';

  13. xrange=115:0.5:136;                  
  14. yrange=35:0.5:55;
  15. [X,Y] = meshgrid(xrange,yrange);

  16. U=griddata(long,latt,u,X,Y);
  17. V=griddata(long,latt,v,X,Y);

  18. %%
  19. figure(1);
  20.    m_proj('miller','lon',[120 , 132],'lat',[36 , 48]);
  21.    ChinaL=shaperead('bou2_4l.shp');
  22.    bou2_4lx=[ChinaL(:).X];
  23.    bou2_4ly=[ChinaL(:).Y];
  24.    hold on;
  25.    m_plot(bou2_4lx,bou2_4ly,'Color',[0.36275,0.36275,0.36275],'linewidth',0.8);%绘制中国省界
  26.    m_gshhs_i('Color',[0.36275,0.36275,0.36275]','LineWidth',0.8);
  27.    m_grid('box','on','tickdir','in','Fontsize',14);
  28.    
  29.    hold on
复制代码
下面开始正式绘图
首先是最常用的m_quiver。官方例子如下:
m_quiver样例.PNG
但是我使用后的效果如下:
  1. m_quiver(X,Y,U,V,'r');
复制代码
m_quiver实际效果.jpg
可以看到,箭头又短又小,一点也不美观,降低了图片的说服力。
查看m_quiver的help内容,重要内容如下:
m_quiver(X,Y,U,V,S) automatically scales the arrows to fit within the grid and then stretches them by S.  Use S=0 to plot the arrows without the automatic scaling; In this case the scaling is 1 unit/degree latitude. Note that we do not scale arrows with respect to map coordinates! Instead, the arrows will correspond better to actual motions over some time step. The tradeoff is that a single scale arrow cannot be accurate for the entire map (M_VEC scales arrows according to map coordinates).
自动翻译一下:
m_quiver(X,Y,U,V,S) 自动缩放箭头以适应网格,然后通过S拉伸它们。使用S=0来绘制不自动缩放的箭头;这种情况下,比例是1单位/纬度。注意,我们不会根据地图坐标缩放箭头!相反,箭头将更好地对应于某一时间步的实际运动。折中之处在于单个缩放箭头不能准确地显示整个地图(M_VEC缩放箭头根据地图坐标)。
反正就是需要通过S来控制箭头大小
修改代码为:
  1. m_quiver(X,Y,U,V,3);
复制代码
m_quiver(X,Y,U,V,3);.jpg
现在的箭头效果已经很明显了,说明默认的S为1。但是还想调整颜色等更多细节

m_quiver(...,LINESPEC) uses the plot linestyle specified for the velocity vectors.  Any marker in LINESPEC is drawn at the base instead of an arrow on the tip.  Use a marker of '.' to specify no marker at all.  See PLOT for other possibilities. m_quiver is a wrapper for QUIVER - for fancier arrows it is possible to replace the call to QUIVER with one to another routine that draws fancy arrows, e.g. ARROW (from TMW user-contrib software archive), or to use M_VEC.
翻译一下:
m_quiver(…,LINESPEC)为速度矢量使用指定的plot LINESPECLINESPEC中的任何标记会绘制在箭头基准位置,同时取消顶端箭头。使用'.' 则没有任何箭头标记。其他属性见函数PLOT。m_quiver是QUIVER的一个包装器——对于更花哨的箭头,可以用一个到另一个绘制花哨箭头的例子来替换对QUIVER的调用,例如ARROW(来自TMW user-contrib software archive),或者使用M_VEC。
这段话的意思是,matlab自带的绘图linespec属性都可以用在这里
但是必须加载S后面,否则会报错。
例如:m_quiver(X,Y,U,V,3,'ro');得到的是下图。注意看图中的红圈位置,理解上面加粗的那句话:
m_quiver(X,Y,U,V,3,'ro');.jpg
最后一个参数‘filled’
  1. m_quiver(...,'filled') fills any markers specified.
复制代码
我试了试没什么效果,暂且一放。
接下来讲上面推荐的更花哨的箭头:m_vec
官方m文件写的很详细,我这里做一下整理
[HP, HT]=m_vec(S,LONG,LAT,VARARGIN) draws arrows as a patch object on a map created by the M_Map package.
       HP: handle to the patch object
       HT: handle to text object if this is a key; see below.
       S:  scale factor, arrow data units per inch.
           It is based on the figure PaperPosition, so be sure to set this (e.g. via "landscape" or "portrait") before calling m_vec.
       LONG,LAT: longitude, latitude of the arrows
           LONG and LAT must have the same dimensions, but can be scalars or vectors; if scalars, multiple arrows can be plotted at a single location.
       VARARGIN can consist of any of the following:
         U,V   U,V,C   Z,U,V,C
       followed by optional arrow parameters,
       followed by optional patch parameters.
         U,V are vectors containing the east and north components of the arrows.
         C is an optional colorspec for all arrows, or an array of CData, one value per arrow.
                  Defaults to black.
         Z is a height in axes data units: this is subject to future modification or omission, and is probably not useful now as-is.
       optional arrow parameters: keyword-value pairs, shown here with default values:
          'headangle',60     degrees: angle of arrow tip
          'headwidth',NaN    points: direct specification of width, instead of headangle
          'headlength',5     points: length of tip; set to 0 to omit arrowhead entirely
          'shaftwidth',1     points: width of arrow shaft
          'centered', 'no'   'yes' to make x,y the arrow  center instead of its tail
          'key', ''          make a labelled horizontal arrow  if the string is not empty; then the string labels the arrow, and the second argument returned, ht, is the handle of the string.
           'edgeclip', 'off'  If 'on' then arrows IN the axes are clipped if their heads are OUT of the axes.

       optional patch parameters: any valid patch properties may be specified here; they are passed directly to the patch function.

     m_vec called without any parameters generates a demonstration plot.
翻译一下:

[HP, HT]=m_vec(S,LONG,LAT,VARARGIN)  在M_Map包创建的map上绘制一个patch对象。

HP:patch对象的句柄

HT:如果是一个key的话,为文本对象的句柄;见下文。

S:比例系数,每英寸内箭头数据单位。它是基于figure PaperPosition,所以在调用m_vec之前一定要设置这个(例如通过"landscape" or "portrait",即“横向”或“纵向”)。

LONG,LAT: 箭头的纬度:经度

LONG和LAT必须有相同的维数,但可以是标量或向量;如果是标量,可以在一个位置绘制多个箭头。

VARARGIN可以由以下任意一个组成:

U, V U, V C Z, U, V, C

后跟可选的箭头参数,

后面是可选的补丁参数。

U V是包含箭头的东、北分量的向量。

C是所有箭头的可选颜色规范,或者是一个CData数组,每个箭头一个值。默认为黑色。

Z是坐标轴数据单位的高度:这可能会受到将来的修改或遗漏,现在可能没有用处。

可选的箭头参数:键-值对,默认值如下:

'headangle',“头角”,默认60度:箭头尖端的角度

'headwidth',“头宽”,默认NaN,直接说明宽度,而不是通过头角

'headlength',“头长”,默认5:头尖长度;设置为0可以完全省略箭头

'shaftwidth','轴宽',默认1:箭轴的宽度

'centered', 'no' 'yes':"居中" "否" "是"让x y作为箭头的中心而不是它的尾部

'key', "如果字符串不为空,则创建一个标有标签的水平箭头;然后字符串为箭头标记,返回的第二个参数ht是字符串的句柄。

'edgeclip',默认 'off',如果'on',当箭头的头部超出坐标轴时,那么轴上的箭头将被剪切。

可选的补丁参数:可以在这里指定任何有效的补丁属性;它们被直接传递给patch函数。

以上就是关键信息。官方样例如下:

m_mvc样例.PNG

先来个夸张的尝试

  1. [HP, HT]=m_vec(100,X,Y,U,V,'k','headangle',30,'headwidth',4,'headlength',7,'shaftwidth', 1,'centered', 'yes');
复制代码

m_vec1.jpg

超边界非常明显,边界处甚至出现了箭头叠加。还有一个特点是箭头的三角形并不是等腰三角形,而是会随着箭头角度发生拉伸。

下面加上'edgeclip','on',再把粗细、颜色等微调一下。

  1. [HP, HT]=m_vec(100,X,Y,U,V,'r','headangle',30,'headwidth',2,'headlength',4,'shaftwidth', 0.5,'centered', 'yes','edgeclip','on');
复制代码

m_vec2.jpg

可以看到,虽然不超边界了,但是边界附近叠加的问题还是没有解决。

即使去掉'centered', 'yes',也只能取消部分边界的叠加,如下图:

m_vec3.jpg


so,结论就是:m_quiver能满足要求的,尽量别用m_vec

如果非要用m_vec,那就需要对数据进行筛选,去掉边界上的数据,如下:

  1. X1=X(4:size(X,1)-15,12:size(X,2)-9);  
  2. Y1=Y(4:size(Y,1)-15,12:size(Y,2)-9);
  3. U1=U(4:size(U,1)-15,12:size(U,2)-9);
  4. V1=V(4:size(V,1)-15,12:size(V,2)-9);
  5. [HP, HT]=m_vec(200,X1,Y1,U1,V1,'b','headangle',30,'headwidth',2.5,'headlength',3.5,'shaftwidth', 0.8,'centered', 'yes','edgeclip','on');
复制代码

m_vec4.jpg


最后一个key属性适用于添加图例,具体可以看源文件,不再啰嗦了。




                               
登录/注册后可看大图


原创不易,点个赞再走啊。

转载请注明出处。


点评

图很漂亮: 5.0 刚好需要: 5.0
谢谢共享: 5.0
图很漂亮: 5 刚好需要: 5 谢谢共享: 5
  发表于 2021-2-23 17:27

评分

参与人数 1金钱 +10 贡献 +5 收起 理由
二爷名声在外 + 10 + 5

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2021-2-24 20:50:45 | 显示全部楼层
学习了{:eb502:}{:eb502:}{:eb502:}
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-6-11 10:27:12 | 显示全部楼层
{:eb502:}{:eb502:}
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-6-11 17:24:52 | 显示全部楼层
目前m_map是不是都用的1.4版?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-6-12 17:44:22 | 显示全部楼层
赞!谢谢楼主
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2021-6-17 14:57:08 | 显示全部楼层
puck66 发表于 2021-6-11 17:24
目前m_map是不是都用的1.4版?

应该是吧?早就不更新了
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-7-11 18:22:50 | 显示全部楼层
楼主太棒了!!
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-7-12 17:07:06 | 显示全部楼层
楼主 ,我用了m-quiver画风场图,调整S大小只有靠近北极90N附近一两行风场长度大小出现变化,其他经纬度地区的风场没有变化,还是像点点一样看不清流场如何
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2021-7-14 09:00:56 | 显示全部楼层
maoxiaohuai_wb 发表于 2021-7-12 17:07
楼主 ,我用了m-quiver画风场图,调整S大小只有靠近北极90N附近一两行风场长度大小出现变化,其他经纬度地 ...

是不是其他地方的风速本来就小啊?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-7-21 10:56:54 | 显示全部楼层
不要90N/S数据更改箭头标尺还是可以改变大小的
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表