MATLAB 矢量图(风场、电场等)标明矢量大小的方法——箭头比例尺及风矢杆图的绘制

2022-09-13 15:22:23 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

作者: 中国科学院大气物理研究所  律成林

摘要:本文主要讲述了在MATLAB中标明矢量图中矢量大小的方法,其中最主要的方法是绘制箭头比例尺。作为运算速度非常快的软件,MATLAB的一个缺点为缺乏在图窗外面绘制箭头比例尺的函数,且m_quiver函数绘制的箭头长度也会受到地图放大系数的影响,而m_vec函数绘制的箭头长度仅与矢量大小本身有关。因而,本人基于m_vec绘制结果,开发了一个可以在Figure内任意位置为指定的矢量图绘制箭头比例尺的函数——m_arrow_scale2,本文已包含该函数的代码,该函数考虑了方方面面,如文本标注、位置、字体等参数,且预设了很多参数供使用者选择,选择的余地非常多,使用起来非常方便,功能也较为强大。此外,想要标明矢量大小的另一个方法是绘制风矢杆图,采用m_windbarb函数。本文详细介绍了上述各种函数,并设置了例题、练习题,含有详细的解析,在讲授知识的同时,又本着“授人以渔”的原则,倾注了作者本人迄今为止对MATLAB近乎所有的深刻理解,也为读者传授MATLAB的核心使用方法,是本人的心血之作。如果读者能够仔细研读此文,对MATLAB编程能力的提升将会是一个质的飞跃。

关键词:箭头比例尺;风矢杆;MATLAB;矢量大小的标注;矢量图

目 录

0 引言

0.1 MATLAB处理数据的优势

0.2 quiver和m_quiver函数的缺陷

1 根据矢量大小确定箭头长度的矢量场绘制——m_vec函数介绍

1.1 m_vec可以画出箭头长度与矢量大小成正比的矢量图

1.2 m_vec的用法——也可在投影图上绘制箭头比例尺,但无法画在投影图外面

2 新开发的绘制箭头比例尺的函数——m_arrow_scale2

2.1 m_arrow_scale2简介

2.2 m_arrow_scale2代码(由中国科学院大气物理研究所2021级直接攻博研究生——律成林(本人)编写)

2.3 m_arrow_scale2的用法详解

2.3.1 m_arrow_scale2的基本用法

2.3.2 通过设置Name-Value值来对箭头比例尺进行微调

2.3.3 输出对象后,直接设置对象属性,以实现对图像其他属性的微调

2.4 练习题(开卷)

3 另一种可直接判断风速大小的矢量图——风矢杆图(m_windbarb)

3.1 什么是风矢杆

3.2 用m_windbarb画风矢杆图

4 总结与讨论


0 引言

0.1 MATLAB处理数据的优势

  MATLAB是一种用于技术计算(technical computing)的高性能语言。在数值天气预报、气候模拟等领域,需要进行大量的运算,对算法的性能及硬件的处理速度比较关注。而MATLAB所使用的算法都是科研和工程计算中的最新研究成果。尤其是在处理大数据时,计算速度非常快,计算精度也非常高。先进的算法使得其计算速度可以是其他软件的几倍甚至是几十倍——别的软件用1分钟才能算出的结果,MATLAB在2~3秒内便可以搞定。

  此外,MATLAB还拥有强大的实时编辑功能,用户可以在想暂停的地方进行断点暂停,而在工作区内所有变量的值一目了然,对用户的手动编程非常友好。MATLAB还拥有强大的绘图功能,绘图速度非常快,图像精确,还可以绘制三维图像并设置光源,绘制动图等。在绘图时,用户也可以点击其中的一些对象,右击查看其属性并进行新的设置。

  美中不足的一点是,MATLAB的自带函数中,没有给矢量图绘制箭头比例尺的函数,这一点需要用户进行手动操作。因而,本文会把这一点不足给弥补上,给读者带来一些关于MATLAB画矢量场以及如何绘制箭头比例尺的内容。并且本人也开发了一个函数——m_arrow_scale2,专门用来绘制箭头比例尺,代码和使用说明放在了本文的第2节中

0.2 quiver和m_quiver函数的缺陷

  众所周知,MATLAB可用quiver以及另外开发的m_map工具包中的m_quiver函数绘制矢量图。m_map的下载和安装教程详见:

MATLAB m_map工具包的安装“三步走”_LV_Chenglin1999的博客-CSDN博客

但若想要绘制箭头比例尺,即显示某一长度的箭头所表示的矢量的大小是多少,则需要手动操作一番。

  在m_map工具包中,对于m_quiver函数,为了美观,其绘制的箭头的长度含有参考地图投影各处的放缩情况而乘以了相应的放大系数的成分,因而有时并不能直接根据其长度的大小来比较不同矢量的大小(如例1)。这也是m_quiver函数所绘制的矢量场在某些时候所画的一个箭头的比例尺意义大减的重要原因。当然也可绘制由地图中心向边缘随位置到圆心的距离的增加而箭头长度递减的二维的或含有很多个箭头的比例尺集合,在这个比例尺集合中,这些箭头的长度是关于位置到圆心的距离的函数,但表现形式会有些复杂,且不易参考。

例1 m_quiver函数绘制的箭头长度是根据地图的放缩比例乘以了一个放大系数,有时并不能直接根据其长度的大小来比较不同矢量的大小。如下代码是在卫星(Satellite)投影中绘制了大小相等的矢量,但在图中箭头的大小却并不相等。

代码语言:javascript复制
[X, Y] = meshgrid(-5 : 1 : 5);
figure('position',[50,100,800,600])
m_proj('Satellite','lon',10,'lat',0,'alt',0.06)
u = [ones(3,11)/sqrt(2);ones(3,11)];
v = [ones(3,11)/sqrt(2);zeros(3,11)];
quiv1 = m_quiver(X(1:2:11,:),Y(1:2:11,:),u,v, ...
     'autoscale', 'on', 'autoscalefactor', 0.55);
m_grid;

图1 在卫星投影上,m_quiver函数绘制的相等大小矢量的箭头长度不等

从代码中的第3、4行可以看出,这些矢量的大小都是相等的,都等于1。但由于采用了卫星(Satellite)的地图投影,不同位置放大系数不同,箭头的大小也不同。在同一纬度上,东边的箭头长度是明显长于西边的箭头长度的;而在同一经度上,靠近赤道的箭头长度也要长于更高纬地区的箭头长度。

  因而,m_quiver有时不便于绘制箭头比例尺,即使绘制了,如果不同地区的放大系数不同,还需要进行额外的指明,不方便直接比较各矢量的大小。

1 根据矢量大小确定箭头长度的矢量场绘制——m_vec函数介绍

1.1 m_vec可以画出箭头长度与矢量大小成正比的矢量图

  m_vec是m_map工具包中的函数,它能够在任意地图投影坐标上绘制出箭头长度与矢量大小成正比的矢量图(例2),从而能从图中直观地比较各矢量的大小。而在此时,按照需要而绘制出的箭头比例尺才能够有意义。

例2 m_vec函数绘制的矢量图,箭头长度与矢量大小成正比。如下代码仍在Satellite投影上绘制了例1中的矢量场,所不同的是使用m_vec函数替代了m_quiver函数。

代码语言:javascript复制
[X, Y] = meshgrid(-5 : 1 : 5);
figure('position', [50, 100, 1300, 600])
ax1 = axes('position', [0.05, 0.05, 0.4, 0.9]);
m_proj('Satellite', 'lon', 10, 'lat', 0, 'alt', 0.06)
u = [ones(3, 11) / sqrt(2); ones(3, 11)];
v = [ones(3, 11) / sqrt(2); zeros(3, 11)];
m_grid
quiv1 = m_vec(5, X(1 : 2 : 11, :), Y(1 : 2 : 11, :), u, v, ...
    'shaftwidth', 1, 'headlength', 5);
ax2 = axes('position', [0.5, 0.05, 0.4, 0.9]);
m_proj('Equidistant cylindrical', 'lon', [-1, 5], 'lat', [-1, 5])
u1 = [1, 1, 1, 1, 2, 2, 4];
v1 = zeros(1, 7);
X1 = [0, 1, 2, 3, 0, 2, 0];
Y1 = [1, 1, 1, 1, 2, 2, 3];
m_grid
col = [1, 0, 0; 0, 0, 1; 0, 0.5, 0; 0.6, 0.2, 0; 1, 0, 0; 0, 0, 1; 0, 0, 0];
quiv2 = m_vec(72/65, X1, Y1, u1, v1, col, 'shaftwidth', 1, 'headlength', 5);

图2 m_vec能画出箭头长度与矢量大小成正比的矢量图

需要注意的是:在使用m_vec之前,一定要先用m_grid绘制好网格,否则绘制出的箭头长度基本上都不正确。

1.2 m_vec的用法——也可在投影图上绘制箭头比例尺,但无法画在投影图外面

  [HP, HT] = m_vec(S, LONG, LAT, U, V)

  [HP, HT] = m_vec(S, LONG, LAT, U, V, Name, Value)

  [HP, HT] = m_vec(S, LONG, LAT, U, V, C, Name, Value)

  S是比例因子,S越大箭头越短,在绘制时可通过多试几次以得到想要的矢量图。

  LONG和LAT是经度和纬度坐标,U,V是对应矢量的东分量大小和北分量大小,C是颜色。

  关于LONG、LAT和U、V的更多用法:当LONG和LAT都只有一个数时,U和V可为有多个值的向量,此时执行的是在一个点上绘制多个不同的箭头。

  Name-Value值作为输入变量排列在u0的后面,Name为属性名称,‘char’(字符)类型;Value为用户根据需要所设定的属性值,跟在Name后面,二者以逗号隔开:

  m_vec(S, LONG, LAT, U, V, C, Name, Value)

  例如设置箭头头部长为6,Name是’headlength’,Value是6,则输入的语句为:

  m_vec(S, LONG, LAT, U, V, C, ‘headlength’, 6)

  用户也可以对多个属性值进行设定:

  m_vec(S, LONG, LAT, U, V, C, Name1, Value1, Name2, Value2, Name3, Value3, …)

  例如设置箭头头部长为6,箭头尾线宽为1.5,去掉超出图窗外的箭头部分:

  m_vec(S, LONG, LAT, U, V, C, ‘headlength’, 6, ‘shaftwidth’, 1.5, ‘edgeclip’, ‘on’)

  后面可接的属性-值对(Name-Value)总共有7个(表1):

‘headangle’

箭头尖端的角度(默认为60,单位为°)

‘headwidth’

箭头头部的宽度(默认为NaN,当被指定为其它值时,‘headangle’失效)

‘headlength’

箭头头部的长度(默认为5,当设为0时省略箭头头部,变为线段)

‘shaftwidth’

箭头尾线宽(默认为1)

‘centered’

若为’yes’,则格点位于箭头的中心;若为’no’(默认),则格点位于箭头的尾端

‘key’

标注文本的内容,默认为”

‘edgeclip’

若为’on’,则超出图窗的箭头部分会被裁减掉;若为‘no’(默认)则依然保留

  而输出项HP是绘制出的箭头图形的patch对象,HT是当有标注文本时的标注文本text对象。对于箭头对象HP关于函数中没有给出的属性的设置,用户可通过

  a = get(HP)

  查看HP中的所有属性值,并用

  set(HP, Name, Value)

  来进行对对象属性值的设定。例如,设定箭头的轮廓线为蓝色:

  set(HP, ‘EdgeColor’, ‘b’)

  对于HT同样如此。

  用户也可以在 https://ww2.mathworks.cn/help/matlab/index.html 网站上输入Patch并回车,点击检索到的第一项,然后在网页的最下方点击“Patch属性”超链接,查阅对象Patch所有的属性的含义和用法。(其它对象属性含义的查阅同上)

  通常无需设置这些属性值,箭头就已经非常美观了,主要设置的还是第一个参数S(比例因子)。微调时常用的属性是‘headlength’和‘shaftwidth’,即箭头头部长和箭头尾部宽,以使箭头看起来更加美观。

  m_vec还可以通过设置‘key’属性值在投影图上绘制箭头比例尺(例3)。

例3 在例2基础上,通过设置m_vec的‘key’属性值直接在投影图上绘制箭头比例尺。

代码语言:javascript复制
[X, Y] = meshgrid(-5 : 1 : 5);
figure('position', [50, 100, 600, 600])
m_proj('Satellite', 'lon', 10, 'lat', 0, 'alt', 0.06)
u = [ones(3, 11) / sqrt(2); ones(3, 11)];
v = [ones(3, 11) / sqrt(2); zeros(3, 11)];
m_grid
quiv1 = m_vec(5, X(1 : 2 : 11, :), Y(1 : 2 : 11, :), u, v, ...
    'shaftwidth', 1, 'headlength', 5);
arr = m_vec(5, 15, 9, 2, 0, 'shaftwidth', 1, 'headlength', 5, 'key', '2 m/s');

图3 m_vec通过设置‘key’属性值直接在投影图上绘制箭头比例尺

  然而,m_vec无法在投影图外面绘制箭头比例尺。通过改变最后一行代码可以了解到,即便把经度、纬度设置到了投影图的外面,依旧是在投影图上绘制箭头比例尺,只不过是在地球的背面。而当整个投影图都需对矢量数据进行绘制的时候,再在投影图上绘制箭头比例尺就不便于辨认了(例4)。因而,本人又开发了一个新的函数,可以在figure内的任意位置绘制任一矢量图的箭头比例尺(见下一节,第2节)。

例4 当采用Satellite投影时,箭头比例尺只能画在投影图上是m_vec的弊端,当整个投影图都绘制了矢量时不便于辨认,因而把箭头比例尺移到图的外面是个需要解决的问题。

代码语言:javascript复制
[X, Y] = meshgrid(-5 : 1 : 5);
figure('position', [50, 100, 600, 600])
m_proj('Satellite', 'lon', 0, 'lat', 0, 'alt', 0.02)
u = [ones(3, 11) / sqrt(2); ones(3, 11)];
v = [ones(3, 11) / sqrt(2); zeros(3, 11)];
m_grid
m_coast('patch', [0.5, 0.5, 0.5]);
hold on
quiv1 = m_vec(5, X(1 : 2 : 11, :), Y(1 : 2 : 11, :), u, v, ...
    'shaftwidth', 1, 'headlength', 5);
arr = m_vec(5, 14, 20, 2, 0, 'shaftwidth', 1, 'key', '2 m/s');

图4 即便是把箭头比例尺的坐标设到了投影图的外面,箭头比例尺依旧在投影图内

2 新开发的绘制箭头比例尺的函数——m_arrow_scale2

2.1 m_arrow_scale2简介

  m_arrow_scale2函数,是由中国科学院大气物理研究所2021级直接攻博研究生——律成林(本人)开发的。它能够在figure中的任意位置画任一矢量图的箭头比例尺,并且使用起来非常简便。它可以通过设置‘position’属性值为 ‘lu’,‘ru’,‘ld’,‘rd’将箭头比例尺绘制在图窗的左上角、右上角、左下角、右下角,还可以自己制定其在figure内的相对位置,并且可以设置标注文本的位置,通过设置‘labelposition’属性值为‘u’,‘d’,将文本设置在箭头的上方、下方,也可以自己指定位置。还可以指定箭头的位置,设置字体,边框线的有无、粗细、颜色,填充颜色和填充的透明度等等。如果用户觉得属性不够用,还可以对各个对象进行手动设置属性值。

  在调用m_arrow_scale2函数前,需将该函数放在MATLAB的根目录中,可以是默认目录,也可以是当前目录。m_arrow_scale2的代码将在下一节(2.2节)给出,用户可将代码复制到m_arrow_scale.m文件中,并将文件放在root目录下或当前目录中。

图5 使用m_arrow_scale2在4个自带位置绘制的箭头比例尺(含文本在箭头上方标注)

2.2 m_arrow_scale2代码(由中国科学院大气物理研究所2021级直接攻博研究生——律成林(本人)编写)

代码语言:javascript复制
%% M_ARROW_SCALE2使用说明
%                   给矢量场图添加箭头比例尺
%                        编程人:律成林(中国科学院大气物理研究所 博士研究生)
%==========================================================================
%    M_ARROW_SCALE2(HP, u, v, u0)
%    M_ARROW_SCALE2(HP, u, v, u0, Name, Value)
%    [arrow, txt, ax, layer] = M_ARROW_SCALE2(___)
%==========================================================================
%                                一、用法
%在使用m_vec函数绘制了矢量场图后([HP, HT] = m_vec(s, lon, lat)),把输出
%的HP代入到m_arrow_scale2函数中绘制箭头比例尺:
%    M_ARROW_SCALE2(HP, u, v, u0)
%其中,u、v分别为为原始矢量场的横向分量和纵向分量,u0为箭头比例尺的指示值。
%在默认情况下,箭头比例尺位于该图右上角的新绘制的白框内,箭头在上,标注文本
%在下。用户也可以通过设定Name-Value值,来进行调整(详见第二节):
%    M_ARROW_SCALE2(HP, u, v, u0, Name, Value)
%也可以通过直接设置对象的属性来进行调整(详见第三节):
%    [arrow, txt, ax, layer] = M_ARROW_SCALE2(___)
%    set(arrow, Name, Value)
%==========================================================================
%                             二、Name-Value值
%例如设置标注文本,Name是'label',Value是'5 m/s',则输入的语句为:
%    M_ARROW_SCALE2(HP, u, v, u0, 'label', '5m/s')
%执行的效果是标注文本为 5m/s。
%----------------------- Name可以不区分大小写 -----------------------------
%Name            含义     Value
%'Label'         标注内容   如'5 m/s'等,char或cell类型(默认为u0对
%                         应的字符)
%'FontName'      标注字体   char或cell类型(默认为'Helvetica')
%'FontSize'      标注字号   数字。单位:榜(默认根据图窗大小确定)
%'FontColor'     标注字颜色  可为'r', 'b'等,也可为[R, G, B]向量(默
%                         认为黑色,'k' / [0, 0, 0])
%'FontWeight'    标注是否加粗 'normal'不加粗(默认),'bold'加粗
%'FontAngle'     标注是否倾斜 'normal'不倾斜(默认),'italic'倾斜
%'Position'      框的位置   可用的Value有:
%                 'lu'/'left_up'/'lt'/'left_top'/'左上':       图窗左上方
%                 'ru'/'right_up'/'rt'/'right_top'/'右上':     图窗右上方
%                 'ld'/'left_down'/'lb'/'left_bottom'/'左下':  图窗左下方
%                 'rd'/'right_down'/'rb'/'right_bottom'/'右下':图窗右下方
%                 [x0, y0, xlength, ylength]:    框左下顶点坐标为[x0, y0]
%                       且长和高分别为xlength和ylength,在figure内的相
%                       对位置,范围为0~1
%'LabelPosition' 标注位置   默认标注在箭头下方。可用的Value有:
%                 'u'/'up'/'t'/'top'/'上':            标注在箭头上方
%                 'd'/'down'/'b'/'bottom'/'下':       标注在箭头下方
%                 [x, y]:   x, y是figure内的相对位置,分别从左、下开始计算,
%                          范围为0~1。标注文本以该位置为中心坐标对齐
%'ArrowPosition' 箭头位置   箭头默认位于标注的上方。可用的Value有:
%                 'u'/'up'/'t'/'top'/'上':            箭头在标注上方
%                 'd'/'down'/'b'/'bottom'/'下':       箭头在标注下方
%                 [x, y]:   x, y是figure内的相对位置,分别从左、下开始计算,
%                          范围为0~1。箭头以该位置为中心坐标对齐
%'BoxStyle'      框线线型   '-'实线(默认),'--'虚线,'-.'点划线,':'点线,
%                         'none'线条不可见
%'BoxColor'      框线颜色   同上面的'FontColor'的Value,此外还可为'none'来
%                         不显示框
%'BoxWidth'   框线宽度   实数。单位:榜(默认为0.5)
%'FaceColor'     填充颜色   同上面的'BoxColor'的Value(默认为白色,'w')
%'FaceAlpha'     填充透明度  0~1,0为完全透明,1为完全不透明(默认为1)
%==========================================================================
%                            三、输出对象
%    [arrow, txt, ax, layer] = M_ARROW_SCALE2(___)
%arrow:    在图窗ax内画出的箭头,类型为 1×1 Patch
%txt:      文本框,类型为 1×1 Text
%ax:       图窗,默认为透明无边框,坐标皆对应figure的相对位置,类型为 Axes
%layer:    装饰图层,最先绘制在ax内,类型为 1×1 Patch
%用户可通过 a = get(arrow) 查看arrow中的所有属性值,并用
%    set(arrow, Name, Value)
%来进行对对象属性值的设定。例如,设定箭头超出图窗的部分不显示:
%    set(ax, 'Clipping', 'on')
%对于txt、ax、layer同样如此。用户也可以在
%https://ww2.mathworks.cn/help/matlab/index.html
%网站上输入Patch并回车,点击检索到的第一项,然后在网页的最下方点击'Patch属性'
%超链接,查阅对象Patch所有的属性的含义和用法。(其他对象属性含义的查阅同上)
%=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
%完成日期:2022年1月22日
%see also: m_vec

function varargout = m_arrow_scale2(var_vec, u, v, u0, varargin)
%% 判断用户输入的参数格式是否正确
if nargin < 4
    warning('您输入的参数少于4个。m_arrow_scale的用法如下:')
    help m_arrow_scale2
    return
end
if nargin > 4
    if mod(length(varargin), 2) > 0
        error('您输入的属性中有值未输入。')
    end
end
%% 切换到矢量图所在的图窗
axes(var_vec.Parent);
%% 获取窗口和图窗的一些属性值
% 窗口位置
gcf_position = get(gcf, 'Position');
gca_position = get(gca, 'Position');
% 图窗长和高
gca_x_length = gcf_position(3) * gca_position(3);
gca_y_length = gcf_position(4) * gca_position(4);
% 图窗x和y的范围
gca_xlim = get(gca, 'XLim');
gca_ylim = get(gca, 'YLim');
%% 判断横纵轴单位长度的长是否相等
if strcmp(get(gca, 'DataAspectRatioMode'), 'manual')
    dx_dy_dz = get(gca, 'DataAspectRatio');
else
    dx_dy_dz = [gca_x_length / (gca_xlim(2) - gca_xlim(1)), ...
        gca_y_length / (gca_ylim(2) - gca_ylim(1)), 1];
end
if dx_dy_dz(1) ~= dx_dy_dz(2)
    warning(['请注意:图窗横纵轴单位长度的长并不相等,比例为 ', ...
        num2str(dx_dy_dz(1)), ' : ', num2str(dx_dy_dz(2)), ' 。'])
end
%% 获取图窗单位长度对应的像素数
% 图窗纵坐标和横坐标的单位长度的长之比
dy_by_dx = dx_dy_dz(2) / dx_dy_dz(1);
% 图窗的未缩放维度和缩放维度的判定(小于0,x未缩放;大于0,y未缩放)
zoom_dimension = gca_x_length / (gca_xlim(2) - gca_xlim(1)) * ...
    (gca_ylim(2) - gca_ylim(1)) * dy_by_dx - gca_y_length;
% 求出x单位长度对应的像素数
if zoom_dimension <= 0
    gca_x_length_real = gca_x_length;
    gca_y_length_real = gca_x_length / (gca_xlim(2) - gca_xlim(1)) * ...
        (gca_ylim(2) - gca_ylim(1)) * dy_by_dx;
    dx_real = gca_x_length / (gca_xlim(2) - gca_xlim(1));
else
    gca_x_length_real = gca_y_length / dy_by_dx / ...
        (gca_ylim(2) - gca_ylim(1)) * (gca_xlim(2) - gca_xlim(1));
    gca_y_length_real = gca_y_length;
    dx_real = gca_x_length_real / (gca_xlim(2) - gca_xlim(1));
end
% 窗口位置
gca_position = [gca_position(1)   (gca_position(3) - gca_x_length_real / gcf_position(3)) / 2, ...
    gca_position(2)   (gca_position(4) - gca_y_length_real / gcf_position(4)) / 2, ...
    gca_x_length_real / gcf_position(3), gca_y_length_real / gcf_position(4)];
% 图窗高
gca_y_length = gcf_position(4) * gca_position(4);
%% 获取箭头参数
x = var_vec.XData(:, 1);
y = var_vec.YData(:, 2);
% 第一个箭头总长度对应的像素、对应的向量大小、箭头比例尺总长度对应的像素
arrow_length = sqrt((x(4, :) - (x(1, :)   x(7, :)) / 2) .^ 2   ...
    (y(4, :) - (y(1, :)   y(7, :)) / 2) .^ 2) * dx_real;
arrow_value = sqrt(u(1) ^ 2   v(1) ^ 2);
arrow_length = arrow_length / arrow_value * u0;
% 箭头尾线宽、头部宽、头部长对应的像素
arrow_width = sqrt((x(7, :) - x(1, :)) .^ 2   ...
    (y(7, :) - y(1, :)) .^ 2) * dx_real;
head_width = sqrt((x(3, :) - x(5, :)) .^ 2   ...
    (y(3, :) - y(5, :)) .^ 2) * dx_real;
head_length = sqrt((x(4, :) - (x(3, :)   x(5, :)) / 2) .^ 2   ...
    (y(4, :) - (y(3, :)   y(5, :)) / 2) .^ 2) * dx_real;
% 箭头边线宽度,边线颜色,填充颜色,和不按照坐标区域裁剪对象
arrow_linewidth = var_vec.LineWidth;
arrow_edgecolor = var_vec.EdgeColor;
arrow_facecolor = var_vec.FaceColor;
%% 确定矢量图的箭头比例尺的各种参数并绘制箭头比例尺
% 标注文本内容、字体、字号、字颜色、字加粗、字倾斜、框线条类型、框颜色、
% 框宽、填充颜色、填充透明度、框位置、文本位置的默认值
new_label = num2str(u0);
new_fontname = 'Helvetica';
new_fontsize = gca_y_length * 0.06 * 0.6;
new_fontcolor = [0, 0, 0];
new_fontweight = 'normal';
new_fontangle = 'normal';
new_boxstyle = '-';
new_boxcolor = [0, 0, 0];
new_boxwidth = 0.5;
new_facecolor = [1, 1, 1];
new_facealpha = 1;
new_position_unsure = 'ru';
new_labelposition_unsure = 'd';
% 箭头比例尺的原始坐标
new_XData = [0; arrow_length - head_length; arrow_length - head_length; ...
    arrow_length; arrow_length - head_length; ...
    arrow_length - head_length; 0] / gcf_position(3);
new_YData = [(head_width   arrow_width) / 2; ...
    (head_width   arrow_width) / 2; head_width; head_width / 2; ...
    0; (head_width - arrow_width) / 2; ...
    (head_width - arrow_width) / 2] / gcf_position(4);
% 用户给定的参数
if nargin > 4
    i = 1;
    while i <= length(varargin)
        if ~ isa(varargin{i}, 'char')
            error("属性名称应为char类型。如文本'lable',字号'fontsize'等。")
        else
            switch lower(varargin{i})
                case 'label'
                    new_label = varargin{i   1};
                case 'fontname'
                    new_fontname = varargin{i   1};
                case 'fontsize'
                    new_fontsize = varargin{i   1};
                case 'fontcolor'
                    new_fontcolor = varargin{i   1};
                case 'fontweight'
                    new_fontweight = varargin{i   1};
                case 'fontangle'
                    new_fontangle = varargin{i   1};
                case 'position'
                    new_position_unsure = varargin{i   1};
                case 'labelposition'
                    new_labelposition_unsure = varargin{i   1};
                case 'arrowposition'
                    new_arrowposition_unsure = varargin{i   1};
                    new_arrowposition_manual = true;
                case 'boxstyle'
                    new_boxstyle = varargin{i   1};
                case 'boxcolor'
                    new_boxcolor = varargin{i   1};
                case 'boxwidth'
                    new_boxwidth = varargin{i   1};
                case 'facecolor'
                    new_facecolor = varargin{i   1};
                case 'facealpha'
                    new_facealpha = varargin{i   1};
                otherwise
                    error('未找到您所要的属性名。')
            end
            i = i   2;
        end
    end
end
% 新图窗的长和高
new_xlim = arrow_length / gcf_position(3) * 1.2;
new_ylim = (new_fontsize / 0.6   head_width * 1.5) / gcf_position(4);
% 新图窗位置
if isa(new_position_unsure, 'char')
    switch lower(new_position_unsure)
        case {'lu', 'left_up', 'lt', 'left_top', '左上'}
            x_begin = gca_position(1);
            y_begin = gca_position(2)   gca_position(4) - new_ylim;
            ax_position = [x_begin, y_begin, new_xlim, new_ylim];
        case{'ru', 'right_up', 'rt', 'right_top', '右上'}
            x_begin = gca_position(1)   gca_position(3) - new_xlim;
            y_begin = gca_position(2)   gca_position(4) - new_ylim;
            ax_position = [x_begin, y_begin, new_xlim, new_ylim];
        case{'ld', 'left_down', 'lb', 'left_bottom', '左下'}
            x_begin = gca_position(1);
            y_begin = gca_position(2);
            ax_position = [x_begin, y_begin, new_xlim, new_ylim];
        case{'rd', 'right_down', 'rb', 'right_bottom', '右下'}
            x_begin = gca_position(1)   gca_position(3) - new_xlim;
            y_begin = gca_position(2);
            ax_position = [x_begin, y_begin, new_xlim, new_ylim];
        otherwise
            error("图窗位置参数输入不正确,有'右上','右下'等。")
    end
else
    if ~ isa(new_position_unsure, 'numeric')
        error(["属性'position'后面对应的值应为4个元素的向量,[最左的", ...
            "位置,最下的位置,长,高],是标准化的数,原则上介于0~1之间。"])
    else
        if length(new_position_unsure) ~= 4
            error(["属性'position'后面对应的值应为4个元素的向量,[最左的", ...
            "位置,最下的位置,长,高],是标准化的数,原则上介于0~1之间。"])
        else
            x_begin = new_position_unsure(1)   ...
                new_position_unsure(3) / 2 - new_xlim / 2;
            y_begin = new_position_unsure(2)   ...
                new_position_unsure(4) / 2 - new_ylim / 2;
            ax_position = new_position_unsure;
        end
    end
end
ax = axes('position', ax_position, 'XLim', ...
    [ax_position(1), ax_position(1)   ax_position(3)], ...
    'YLim', [ax_position(2), ax_position(2)   ax_position(4)]);
an = patch(ax, [ax_position(1), ax_position(1)   ax_position(3), ...
    ax_position(1)   ax_position(3), ax_position(1)], [ax_position(2), ...
    ax_position(2), ax_position(2)   ax_position(4), ax_position(2)   ...
    ax_position(4)], new_boxcolor, 'LineStyle', new_boxstyle, ...
    'LineWidth', new_boxwidth, 'FaceColor', ...
    new_facecolor, 'FaceAlpha', new_facealpha);
% 文本位置和箭头坐标位置
if isa(new_labelposition_unsure, 'char')
    switch lower(new_labelposition_unsure)
        case {'u', 'up', 't', 'top', '上'}
            txt_position = [x_begin   new_xlim / 2, y_begin   ...
                (head_width * 1.5   new_fontsize / 1.2) / gcf_position(4)];
            arr_position = [x_begin   new_xlim / 12, ...
                y_begin   head_width * 0.5 / gcf_position(4)];
        case{'d', 'down', 'b', 'bottom', '下'}
            txt_position = [x_begin   new_xlim / 2, ...
                y_begin   new_fontsize / 1.2 / gcf_position(4)];
            arr_position = [x_begin   new_xlim / 12, ...
                y_begin   new_fontsize / 0.6 / gcf_position(4)];
        otherwise
            error("文本位置参数输入不正确,请输入'上'或'下'。")
    end
else
    if ~ isa(new_labelposition_unsure, 'numeric')
        error("属性'labelposition'后面的值应为2个元素的向量,[x, y]。")
    else
        if length(new_labelposition_unsure) ~= 2
            error("属性'labelposition'后面的值应为2个元素的向量,[x, y]。")
        else
            txt_position = new_labelposition_unsure;
            if new_labelposition_unsure(2) > y_begin   new_ylim / 2
                arr_position = [x_begin   new_xlim / 12, ...
                    y_begin   head_width * 0.5 / gcf_position(4)];
            else
                arr_position = [x_begin   new_xlim / 12, ...
                    y_begin   new_fontsize / 0.6 / gcf_position(4)];
            end
        end
    end
end
if exist('new_arrowposition_unsure', 'var')
    if isa(new_labelposition_unsure, 'char')
        switch lower(new_labelposition_unsure)
            case {'u', 'up', 't', 'top', '上'}
                if exist('new_arrowposition_manual', 'var')
                    arr_position = [x_begin   new_xlim / 12, ...
                        y_begin   head_width * 0.5 / gcf_position(4)];
                else
                    txt_position = [x_begin   new_xlim / 2, ...
                        y_begin   new_fontsize / 1.2 / gcf_position(4)];
                    arr_position = [x_begin   new_xlim / 12, ...
                        y_begin   head_width * 0.5 / gcf_position(4)];
                end
            case{'d', 'down', 'b', 'bottom', '下'}
                if exist('new_arrowposition_manual', 'var')
                    arr_position = [x_begin   new_xlim / 12, ...
                        y_begin   new_fontsize / 0.6 / gcf_position(4)];
                else
                    txt_position = [x_begin   new_xlim / 2, y_begin   ...
                        (head_width * 1.5   new_fontsize / 1.2) / ...
                        gcf_position(4)];
                    arr_position = [x_begin   new_xlim / 12, ...
                        y_begin   new_fontsize / 0.6 / gcf_position(4)];
                end
            otherwise
                error("箭头位置参数输入不正确,请输入'上'或'下'。")
        end
    else
        if ~ isa(new_arrowposition_unsure, 'numeric')
            error("属性'arrowposition'后面的值应为[x, y]。")
        else
            if length(new_arrowposition_unsure) ~= 2
                error("属性'arrowposition'后面的值应为[x, y]。")
            else
                arr_position = [new_arrowposition_unsure(1) - ...
                    arrow_length / gcf_position(3) / 2, ...
                    new_arrowposition_unsure(2) - head_width / ...
                    gcf_position(4) / 2];
                if ~ exist('new_arrowposition_manual', 'var')
                    if new_arrowposition_unsure(2) >= y_begin   ...
                            new_ylim / 2
                        txt_position = [x_begin   new_xlim / 2, ...
                            y_begin   new_fontsize / 1.2 / ...
                            gcf_position(4)];
                    elseif new_arrowposition_manual
                        txt_position = [x_begin   new_xlim / 2, ...
                            y_begin   (head_width * 1.5   ...
                            new_fontsize / 1.2) / gcf_position(4)];
                    end
                end
            end
        end
    end
end
txt = text(ax, txt_position(1), txt_position(2), new_label, ...
    'HorizontalAlignment', 'center', 'FontName', new_fontname, ...
    'FontSize', new_fontsize, 'Color', new_fontcolor, 'FontWeight', ...
    new_fontweight, 'FontAngle', new_fontangle);
arr = patch(ax, new_XData   arr_position(1), new_YData   ...
    arr_position(2), arrow_facecolor, 'EdgeColor', arrow_edgecolor, ...
    'LineWidth', arrow_linewidth, ...
    'Clipping', 'off');
set(ax,'Clipping', 'off', 'XTick', [], 'YTick', [], ...
    'Color', 'none', 'Box', 'off', 'XColor', 'none', 'YColor', 'none');
switch nargout
    case 1
        varargout{1} = arr;
    case 2
        varargout{1} = arr;
        varargout{2} = txt;
    case 3
        varargout{1} = arr;
        varargout{2} = txt;
        varargout{3} = ax;
    case 4
        varargout{1} = arr;
        varargout{2} = txt;
        varargout{3} = ax;
        varargout{4} = an;
end
end

2.3 m_arrow_scale2的用法详解

  在想要得知m_arrow_scale2的用法时,用户也可以在MATLAB中执行“help m_arrow_scale2”获取该函数的帮助。使用说明也以备注的形式放在了m_arrow_scale2.m的最前面,以在执行help m_arrow_scale2时显示这些使用说明。本节中共三个小节内容,分别阐述以下三种用法:

  ① m_arrow_scale2(HP, u, v, u0)

  ② m_arrow_scale2(HP, u, v, u0, Name, Value)

  ③ [arrow, txt, ax, layer] = m_arrow_scale2(___)

2.3.1 m_arrow_scale2的基本用法

第一步:使用m_vec函数绘制矢量场图,需要把HP输出出来

  [HP, HT] = m_vec(s, lon, lat))

  关于m_vec的详细用法,读者可以参见1.2节。

第二步:把输出的HP代入到m_arrow_scale2函数中绘制箭头比例尺:

  m_arrow_scale2(HP, u, v, u0)

  其中,u、v分别为为原始矢量场的东分量大小和北分量大小,u0为箭头比例尺的指示值。

  在默认情况下,箭头比例尺位于该图右上角的新绘制的黑边白框内,箭头在上,标注文本在下。用户也可以通过设定Name-Value值,来进行调整(详见下一节,2.3.2)。

2.3.2 通过设置Name-Value值来对箭头比例尺进行微调

  Name-Value值作为输入变量排列在u0的后面,Name为属性名称,‘char’(字符)类型;Value为用户根据需要所设定的属性值,跟在Name后面,二者以逗号隔开:

  m_arrow_scale2(HP, u, v, u0, Name, Value)

  例如设置标注文本为‘5m/s’,Name是‘label’,Value是‘5m/s’,则输入的语句为:

  m_arrow_scale2(HP, u, v, u0, ‘label’, ‘5m/s’)

  执行的效果是标注文本为 5m/s。

  用户也可以对多个属性值进行设定:

  m_arrow_scale2(HP, u, v, u0, Name1, Value1, Name2, Value2, Name3, Value3, …)

  例如设置标注文本为‘5m/s’,箭头比例尺位于图窗的左下角,标注文本在箭头上方:

  m_arrow_scale2(HP, u, v, u0, ‘label’, ‘5 m/s’, ‘position’, ‘左下’, ‘labelposition’, ‘上’)

  表2给出了m_arrow_scale2可设定的所有属性名称Name、属性值Value和含义。在使用m_arrow_scale2时,输入的属性名称Name可以不区分大小写。

Name

含义

Value

‘Label’

标注内容

如’5 m/s’等,char或cell类型(默认为u0对应的字符)

‘FontName’

标注字体

char或cell类型(默认为’Helvetica’)

‘FontSize’

标注字号

数字。单位:榜(默认根据图窗大小确定)

‘FontColor’

标注字颜色

可为’r’, ‘b’等,也可为[R, G, B]向量(默认为黑色,’k’)

‘FontWeight’

标注是否加粗

‘normal’不加粗(默认),’bold’加粗

‘FontAngle’

标注是否倾斜

‘normal’不倾斜(默认),’italic’倾斜

‘Position’

框的位置

框默认放在图窗的右上角。可用的Value有:

‘lu’/’left_up’/’lt’/’left_top’/’左上’

图窗左上方

‘ru’/’right_up’/’rt’/’right_top’/’右上’

图窗右上方

‘ld’/’left_down’/’lb’/’left_bottom’/’左下’

图窗左下方

‘rd’/’right_down’/’rb’/’right_bottom’/’右下’

图窗右下方

[x0, y0, xlength, ylength]

框左下顶点坐标为[x0, y0]且长和高分别为xlength和ylength,表示在figure内的相对位置,范围为0~1

‘LabelPosition’

标注位置

标注默认在箭头下方。可用的Value有:

‘u’/’up’/’t’/’top’/’上’

标注在箭头上方

‘d’/’down’/’b’/’bottom’/’下’

标注在箭头下方

[x, y]

x, y是figure内的相对位置,分别从左、下开始计算,范围为0~1。标注文本以该位置为中心坐标对齐

‘ArrowPosition’

箭头位置

箭头默认位于标注的上方。可用的Value有:

‘u’/’up’/’t’/’top’/’上’

箭头在标注上方

‘d’/’down’/’b’/’bottom’/’下’

箭头在标注下方

[x, y]

x, y是figure内的相对位置,分别从左、下开始计算,范围为0~1。箭头以该位置为中心坐标对齐

‘BoxStyle’

框线线型

‘-‘实线(默认),’–‘虚线,’-.’点划线,’:’点线,’none’线条不可见

‘BoxColor’

框线颜色

同上面的’FontColor’的Value,不可以设置为’none’(如果想要线条不可见,需设置’BoxStyle’属性值为’none’)

‘BoxWidth’

框线宽度

实数。单位:榜(默认为0.5)

‘FaceColor’

填充颜色

同上面的’BoxColor’的Value,此外还可为’none’来不显示框(默认为白色,’w’)

‘FaceAlpha’

填充透明度

0~1,0为完全透明,1为完全不透明(默认为1)

2.3.3 输出对象后,直接设置对象属性,以实现对图像其他属性的微调

  m_arrow_scale2共创建了四个对象(输出顺序、含义见下式及表3)。

  [arrow, txt, ax, layer] = m_arrow_scale2(___)

对象

含义

arrow

在图窗ax内画出的箭头,类型为Patch

txt

文本框,类型为Text

ax

图窗,默认为透明无边框,坐标皆对应figure的相对位置,类型为 Axes

layer

装饰图层,最先绘制在ax内,类型为Patch

  用户可通过

  a = get(arrow)

  查看arrow中的所有属性值,并用

  set(arrow, Name, Value)

  来进行对对象属性值的设定。例如,设定箭头超出图窗的部分不显示:

  set(ax, ‘Clipping’, ‘on’)

  对于txt、ax、layer同样如此。

  用户也可以在 MATLABDocumentation- MathWorks 中国 网站上输入Patch并回车,点击检索到的第一项,然后在网页的最下方点击“Patch属性”超链接,查阅对象Patch所有的属性的含义和用法。(其它对象属性含义的查阅同上)

2.4 练习题(开卷)

  “授人以鱼不如授人以渔”。本练习题旨在培养读者的思考和理解能力,教会读者在日后使用MATLAB编程时,如遇到不会的问题,能够使用一些技巧从而独立解决问题。希望读者在做该题目时理解力和推理能力能够得到锻炼。

2021年12月的纬向风场(u)、纬向风异常场(ua)、经向风场(v)、经向风异常场(va)分别如表4、表5、表6、表7所示。请在一张图上绘制2021年12月30°S-30°N、180°-120°W的风矢量图和异常风矢量图,要求如下(总分100分):

(1) 采用卫星(Satellite)投影(5分),调整合适的角度、使所有数据点都位于投影面的表面(5分);

  (2) 能画出所给数据的风矢量图(5分),相等大小矢量的箭头长度相等(5分),箭头的长度合适(5分);

  (3) 把风矢量图和异常风矢量图画在同一个图窗上、且位置正确(5分),风矢量用黑色箭头,异常风矢量用红色箭头(5分);

  (4) 绘制海岸线、把陆地填充为灰色——[0.5, 0.5, 0.5](5分),把海洋填充为浅蓝色——[0.45, 0.73, 1](5分);

  (5) 风异常场的箭头比例尺位于左下角且边界紧贴图窗(5分),比例尺长度指示的矢量大小正确(5分),比例尺的标注文本的内容包含了“m/s”(5分),文字标注在箭头的上方(5分);风场比例尺也位于图窗的左下方(5分),且风场比例尺外边界紧贴着风异常场比例尺外边界、位于风异常场比例尺的正上方(5分),比例尺的框内填充为白色、可设填充透明度为0.5(5分),框由宽为0.5的黑实线勾勒(5分);两个比例尺的中间没有黑线、即这两个比例尺都在同一个黑框内(5分);

  (6) 图上有经纬网络(5分),且赤道纬线圈的标注不是“0°”而是“EQ”(5分)。

lat(°) u(m/s) lon(°)

180

175W

170W

165W

160W

155W

150W

145W

140W

135W

130W

125W

120W

30N

-3.45

-5.89

-9.08

-10.49

-9.52

-7.03

-5.11

-4.17

-2.91

-1.34

0.81

2.68

3.73

25N

-2.81

-2.76

-4.82

-7.30

-8.66

-9.11

-9.01

-7.48

-5.78

-5.26

-4.44

-3.79

-1.01

20N

-3.14

-2.58

-3.51

-5.62

-5.76

-5.50

-7.45

-7.97

-7.02

-6.86

-6.38

-6.34

-5.27

15N

-5.17

-4.31

-3.85

-5.77

-7.54

-7.01

-7.08

-7.38

-6.98

-7.66

-8.70

-8.41

-7.98

10N

-5.63

-5.12

-4.90

-4.97

-5.58

-5.13

-5.32

-7.31

-8.33

-7.53

-5.56

-3.63

-3.32

5N

-5.24

-4.74

-5.48

-6.19

-6.59

-6.63

-6.75

-7.10

-6.76

-5.71

-4.33

-3.55

-2.24

0

-6.49

-7.33

-8.15

-8.39

-8.89

-10.46

-10.77

-9.09

-7.48

-6.47

-7.07

-7.48

-6.54

S5

-5.06

-5.99

-6.76

-7.28

-7.68

-8.94

-9.06

-7.80

-7.67

-7.07

-7.66

-7.72

-7.69

10S

-3.09

-4.08

-4.67

-5.41

-5.48

-4.96

-5.38

-5.89

-6.42

-6.65

-7.64

-8.72

-9.71

15S

-3.62

-3.93

-3.88

-3.70

-4.54

-4.50

-4.61

-5.24

-6.09

-7.17

-6.99

-6.95

-7.91

20S

-5.31

-4.89

-4.96

-4.32

-4.75

-5.36

-4.71

-3.82

-4.12

-5.17

-5.70

-5.46

-5.37

25S

-4.98

-4.77

-5.13

-5.54

-5.03

-4.04

-3.40

-3.30

-3.73

-3.97

-5.18

-5.51

-5.43

30S

-4.33

-4.68

-4.99

-6.15

-6.30

-5.19

-4.08

-3.31

-3.71

-4.54

-5.23

-4.61

-4.24

lat(°) ua(m/s) lon(°)

180

175W

170W

165W

160W

155W

150W

145W

140W

135W

130W

125W

120W

30N

-5.19

-7.40

-10.37

-11.39

-9.75

-6.87

-4.53

-2.92

-1.31

0.41

1.67

1.80

1.42

25N

-0.48

-0.27

-2.18

-4.80

-5.41

-4.72

-3.94

-2.00

-0.29

0.48

0.77

0.39

0.47

20N

3.19

3.31

2.67

0.49

-0.85

-0.68

-0.88

0.10

1.39

1.52

0.85

0.20

-0.06

15N

3.54

3.99

4.32

2.79

1.12

1.45

1.54

1.48

1.96

1.50

0.11

-0.44

-1.26

10N

2.80

3.34

3.38

3.47

3.52

3.88

3.28

1.16

-0.35

-0.31

1.04

2.30

2.02

5N

0.91

1.35

0.89

0.59

0.12

0.02

0.00

-0.70

-0.64

0.20

1.09

1.04

1.63

0

-2.96

-2.91

-2.99

-2.90

-3.00

-4.05

-4.07

-2.31

-0.38

0.18

-0.48

-0.89

-0.44

S5

-3.99

-3.78

-3.56

-3.53

-3.22

-3.75

-3.39

-1.83

-0.75

-0.01

-0.51

-0.84

-0.96

10S

-1.73

-2.74

-2.86

-2.72

-2.11

-1.05

-0.77

-1.19

-1.09

-0.48

-0.70

-1.28

-1.93

15S

-0.62

-0.55

-0.41

-0.23

-1.08

-1.90

-1.92

-1.14

-0.72

-1.12

-0.66

-0.34

-0.98

20S

-0.08

0.28

0.19

0.43

-0.26

-1.15

-0.50

0.44

0.00

-0.77

-0.65

0.13

0.64

25S

0.47

0.19

0.02

-0.40

-0.43

0.25

0.80

0.64

0.18

-0.33

-1.63

-1.70

-1.42

30S

-1.85

-1.84

-1.94

-2.90

-2.86

-1.86

-1.07

-0.71

-1.27

-2.28

-2.85

-2.27

-2.09

lat(°) v(m/s) lon(°)

180

175W

170W

165W

160W

155W

150W

145W

140W

135W

130W

125W

120W

30N

-4.30

-1.27

1.64

1.66

0.10

-0.81

-1.46

-2.21

-2.81

-2.66

-1.92

-2.44

-3.03

25N

-4.54

-1.39

1.35

1.83

0.09

-0.95

-1.36

-2.45

-2.90

-2.94

-2.68

-2.84

-3.58

20N

-3.28

-1.45

0.40

1.79

-0.01

-1.52

-0.77

-2.27

-3.59

-3.48

-3.52

-3.63

-3.91

15N

-2.75

-1.92

-0.62

1.11

0.11

-1.54

-1.29

-2.92

-4.29

-3.56

-3.05

-2.97

-3.05

10N

-2.76

-1.60

-0.43

0.12

0.39

0.10

-2.23

-3.74

-3.59

-2.28

-0.23

1.08

-0.19

5N

0.07

0.65

1.60

1.68

2.63

2.58

-2.12

-3.20

-1.48

0.60

3.49

4.81

2.55

0

-0.22

0.01

0.55

0.68

1.73

1.49

-1.12

-1.49

-0.49

1.33

3.24

3.98

2.99

S5

-2.86

-2.08

-1.65

-1.24

-1.35

-2.01

-0.69

-0.37

-0.21

1.37

2.22

3.09

3.00

10S

-2.60

-2.09

-1.83

-1.22

-1.79

-2.04

-0.23

0.23

0.26

0.92

0.55

1.23

1.96

15S

-2.11

-1.33

-1.22

-1.60

-1.54

-0.64

-0.76

-0.61

-0.82

-0.13

0.25

-0.58

-0.43

20S

-1.02

0.41

0.56

-0.22

-1.44

-0.53

-0.06

-0.24

-1.51

-1.32

-0.17

-0.71

-2.64

25S

-0.67

-0.05

0.64

1.39

-0.13

0.09

0.84

-0.34

-1.79

-1.97

-1.21

0.86

-2.55

30S

-0.74

-1.15

-0.91

0.17

1.26

1.79

1.73

0.84

-0.71

-1.72

-1.97

0.40

-1.60

lat(°) va(m/s) lon(°)

180

175W

170W

165W

160W

155W

150W

145W

140W

135W

130W

125W

120W

30N

-4.66

-1.70

1.05

0.66

-1.08

-2.57

-3.79

-4.24

-3.83

-2.48

0.06

1.90

1.50

25N

-3.73

-0.56

1.61

2.17

0.67

-1.50

-2.32

-2.94

-2.55

-1.10

-0.03

1.00

1.05

20N

-1.09

0.33

1.53

3.05

1.40

-0.84

-0.16

-0.57

-1.19

-0.19

0.43

1.09

1.01

15N

-0.15

0.45

1.39

2.48

1.86

1.44

1.80

0.46

-0.56

0.47

1.40

1.63

1.27

10N

-0.37

0.64

1.76

2.33

2.76

2.71

0.68

-0.79

-0.64

0.41

2.22

2.71

1.08

5N

1.32

1.99

2.72

2.76

3.64

3.39

-0.62

-2.32

-0.97

0.76

2.87

3.43

1.20

0

0.89

1.16

1.86

1.87

2.49

2.20

-0.23

-1.34

-0.69

1.09

2.22

2.16

1.06

S5

-0.75

-0.08

0.20

0.69

0.57

-0.35

0.32

0.57

0.12

1.05

1.41

1.50

0.79

10S

-1.50

-0.44

0.02

0.69

0.39

-0.12

0.87

0.82

0.70

0.90

0.09

0.17

0.27

15S

-2.26

-1.37

-0.88

-0.39

-0.19

0.45

0.97

0.89

0.74

0.79

0.62

-0.65

-0.89

20S

-2.05

-0.94

-0.61

-0.92

-1.99

-1.16

0.56

0.87

-0.15

-0.11

0.96

-0.06

-2.14

25S

-2.38

-1.66

-0.52

-0.10

-1.29

-1.08

0.35

-0.02

-1.02

-0.77

0.24

1.92

-1.36

30S

-1.21

-1.62

-1.37

-0.55

0.55

0.80

1.20

0.89

-0.42

-0.99

-0.64

1.88

-0.24

  图像样例如图6。

图6 2021年12月赤道中东太平洋风场(黑色箭头)和风异常场(红色箭头)

代码语言:javascript复制
[u, ua, v, va] = get_data(); %为了看起来整洁,数据的输入放在了后面的函数中
lon = 180 : 5 : 240;
lat = 30 : -5 : -30;
[X, Y] = meshgrid(lon, lat); %X、Y为lon、lat的网格横纵坐标
fig = figure('position', [50, 100, 600, 600]); %创建figure
ax = axes; %创建图窗
m_proj('satellite', 'lon', 210, 'lat', 0, 'alt', 2);        %设置投影图为
%          satellite,观察者角度为EQ、150°W上方距离地表0.6个地球半径的太空中
hold on %保留痕迹,继续绘图
m_coast('patch', [0.5, 0.5, 0.5]); %填充陆地
m_grid('xtick', 180:30:240, 'ytick', [-30, 30], 'backgroundcolor', ...
    [0.45, 0.73, 1], 'xaxislocation', 'middle', 'fontsize', 8) %添加网格,填充海洋
HP1 = m_vec(36, X, Y, u, v, 'headlength', 4, 'shaftwidth', 0.8);
HP2 = m_vec(15, X, Y, ua, va, 'r','headlength', 4, 'shaftwidth', 0.8);
[~, ~, ax_scale, layer] = m_arrow_scale2(HP2, ua, v, 10, 'label', '10 m/s', ...
    'position', '左下', 'labelposition', 'u', 'facecolor', 'w', ...
    'facealpha', 0.5, 'boxcolor', 'k', 'fontsize', 10, 'fontcolor', 'r');
lpos = get(ax_scale, 'position');
XData = [lpos(1), lpos(1)   lpos(3), lpos(1)   lpos(3), lpos(1)];
YData = [lpos(2), lpos(2), lpos(2)   2 * lpos(4), lpos(2)   2 * lpos(4)];
set(layer, 'XData', XData, 'YData', YData);
m_arrow_scale2(HP1, u, v, 20, 'label', '20m/s', 'position', [lpos(1), ...
    lpos(2)   lpos(4), lpos(3), lpos(4)], 'labelposition', 'u', 'facecolor', ...
    'none', 'boxstyle', 'none', 'fontsize', 10);
lwd = get(gca, 'linewidth');
axes(ax);
plt = m_plot(100 : 1 : 300, zeros(1, 201), ':k', 'linewidth', lwd);
plt_x = get(plt, 'XData');
plt_y = get(plt, 'YData');
pos = find(~ isnan(plt_x));
text(plt_x(pos(1)), plt_y(pos(1)), 'EQ', 'HorizontalAlignment', 'right', ...
    'VerticalAlignment', 'middle', 'fontsize', 8, 'color', 'k')
set(gcf, 'color', 'w')
function [u, ua, v, va] = get_data()
u = [-3.45,-5.89,-9.08,-10.49,-9.52,-7.03,-5.11,-4.17,-2.91,-1.34,0.81,2.68,3.73;
-2.81,-2.76,-4.82,-7.30,-8.66,-9.11,-9.01,-7.48,-5.78,-5.26,-4.44,-3.79,-1.01;
-3.14,-2.58,-3.51,-5.62,-5.76,-5.50,-7.45,-7.97,-7.02,-6.86,-6.38,-6.34,-5.27;
-5.17,-4.31,-3.85,-5.77,-7.54,-7.01,-7.08,-7.38,-6.98,-7.66,-8.70,-8.41,-7.98;
-5.63,-5.12,-4.90,-4.97,-5.58,-5.13,-5.32,-7.31,-8.33,-7.53,-5.56,-3.63,-3.32;
-5.24,-4.74,-5.48,-6.19,-6.59,-6.63,-6.75,-7.10,-6.76,-5.71,-4.33,-3.55,-2.24;
-6.49,-7.33,-8.15,-8.39,-8.89,-10.46,-10.77,-9.09,-7.48,-6.47,-7.07,-7.48,-6.54;
-5.06,-5.99,-6.76,-7.28,-7.68,-8.94,-9.06,-7.80,-7.67,-7.07,-7.66,-7.72,-7.69;
-3.09,-4.08,-4.67,-5.41,-5.48,-4.96,-5.38,-5.89,-6.42,-6.65,-7.64,-8.72,-9.71;
-3.62,-3.93,-3.88,-3.70,-4.54,-4.50,-4.61,-5.24,-6.09,-7.17,-6.99,-6.95,-7.91;
-5.31,-4.89,-4.96,-4.32,-4.75,-5.36,-4.71,-3.82,-4.12,-5.17,-5.70,-5.46,-5.37;
-4.98,-4.77,-5.13,-5.54,-5.03,-4.04,-3.40,-3.30,-3.73,-3.97,-5.18,-5.51,-5.43;
-4.33,-4.68,-4.99,-6.15,-6.30,-5.19,-4.08,-3.31,-3.71,-4.54,-5.23,-4.61,-4.24];
ua = [-5.19,-7.40,-10.37,-11.39,-9.75,-6.87,-4.53,-2.92,-1.31,0.41,1.67,1.80,1.42;
-0.48,-0.27,-2.18,-4.80,-5.41,-4.72,-3.94,-2.00,-0.29,0.48,0.77,0.39,0.47;
3.19,3.31,2.67,0.49,-0.85,-0.68,-0.88,0.10,1.39,1.52,0.85,0.20,-0.06;
3.54,3.99,4.32,2.79,1.12,1.45,1.54,1.48,1.96,1.50,0.11,-0.44,-1.26;
2.80,3.34,3.38,3.47,3.52,3.88,3.28,1.16,-0.35,-0.31,1.04,2.30,2.02;
0.91,1.35,0.89,0.59,0.12,0.02,0.00,-0.70,-0.64,0.20,1.09,1.04,1.63;
-2.96,-2.91,-2.99,-2.90,-3.00,-4.05,-4.07,-2.31,-0.38,0.18,-0.48,-0.89,-0.44;
-3.99,-3.78,-3.56,-3.53,-3.22,-3.75,-3.39,-1.83,-0.75,-0.01,-0.51,-0.84,-0.96;
-1.73,-2.74,-2.86,-2.72,-2.11,-1.05,-0.77,-1.19,-1.09,-0.48,-0.70,-1.28,-1.93;
-0.62,-0.55,-0.41,-0.23,-1.08,-1.90,-1.92,-1.14,-0.72,-1.12,-0.66,-0.34,-0.98;
-0.08,0.28,0.19,0.43,-0.26,-1.15,-0.50,0.44,0.00,-0.77,-0.65,0.13,0.64;
0.47,0.19,0.02,-0.40,-0.43,0.25,0.80,0.64,0.18,-0.33,-1.63,-1.70,-1.42;
-1.85,-1.84,-1.94,-2.90,-2.86,-1.86,-1.07,-0.71,-1.27,-2.28,-2.85,-2.27,-2.09];
v = [-4.30,-1.27,1.64,1.66,0.10,-0.81,-1.46,-2.21,-2.81,-2.66,-1.92,-2.44,-3.03;
-4.54,-1.39,1.35,1.83,0.09,-0.95,-1.36,-2.45,-2.90,-2.94,-2.68,-2.84,-3.58;
-3.28,-1.45,0.40,1.79,-0.01,-1.52,-0.77,-2.27,-3.59,-3.48,-3.52,-3.63,-3.91;
-2.75,-1.92,-0.62,1.11,0.11,-1.54,-1.29,-2.92,-4.29,-3.56,-3.05,-2.97,-3.05;
-2.76,-1.60,-0.43,0.12,0.39,0.10,-2.23,-3.74,-3.59,-2.28,-0.23,1.08,-0.19;
0.07,0.65,1.60,1.68,2.63,2.58,-2.12,-3.20,-1.48,0.60,3.49,4.81,2.55;
-0.22,0.01,0.55,0.68,1.73,1.49,-1.12,-1.49,-0.49,1.33,3.24,3.98,2.99;
-2.86,-2.08,-1.65,-1.24,-1.35,-2.01,-0.69,-0.37,-0.21,1.37,2.22,3.09,3.00;
-2.60,-2.09,-1.83,-1.22,-1.79,-2.04,-0.23,0.23,0.26,0.92,0.55,1.23,1.96;
-2.11,-1.33,-1.22,-1.60,-1.54,-0.64,-0.76,-0.61,-0.82,-0.13,0.25,-0.58,-0.43;
-1.02,0.41,0.56,-0.22,-1.44,-0.53,-0.06,-0.24,-1.51,-1.32,-0.17,-0.71,-2.64;
-0.67,-0.05,0.64,1.39,-0.13,0.09,0.84,-0.34,-1.79,-1.97,-1.21,0.86,-2.55;
-0.74,-1.15,-0.91,0.17,1.26,1.79,1.73,0.84,-0.71,-1.72,-1.97,0.40,-1.60];
va = [-4.66,-1.70,1.05,0.66,-1.08,-2.57,-3.79,-4.24,-3.83,-2.48,0.06,1.90,1.50;
-3.73,-0.56,1.61,2.17,0.67,-1.50,-2.32,-2.94,-2.55,-1.10,-0.03,1.00,1.05;
-1.09,0.33,1.53,3.05,1.40,-0.84,-0.16,-0.57,-1.19,-0.19,0.43,1.09,1.01;
-0.15,0.45,1.39,2.48,1.86,1.44,1.80,0.46,-0.56,0.47,1.40,1.63,1.27;
-0.37,0.64,1.76,2.33,2.76,2.71,0.68,-0.79,-0.64,0.41,2.22,2.71,1.08;
1.32,1.99,2.72,2.76,3.64,3.39,-0.62,-2.32,-0.97,0.76,2.87,3.43,1.20;
0.89,1.16,1.86,1.87,2.49,2.20,-0.23,-1.34,-0.69,1.09,2.22,2.16,1.06;
-0.75,-0.08,0.20,0.69,0.57,-0.35,0.32,0.57,0.12,1.05,1.41,1.50,0.79;
-1.50,-0.44,0.02,0.69,0.39,-0.12,0.87,0.82,0.70,0.90,0.09,0.17,0.27;
-2.26,-1.37,-0.88,-0.39,-0.19,0.45,0.97,0.89,0.74,0.79,0.62,-0.65,-0.89;
-2.05,-0.94,-0.61,-0.92,-1.99,-1.16,0.56,0.87,-0.15,-0.11,0.96,-0.06,-2.14;
-2.38,-1.66,-0.52,-0.10,-1.29,-1.08,0.35,-0.02,-1.02,-0.77,0.24,1.92,-1.36;
-1.21,-1.62,-1.37,-0.55,0.55,0.80,1.20,0.89,-0.42,-0.99,-0.64,1.88,-0.24];
end

答案解析:

  (1)在例2中选用了不同的投影图,读者可以根据例2得出,投影图的选择用m_proj函数,卫星投影则把第一个参数设为‘Satellite’。通过比较例3和例4,从不同视角看地球,从代码的不同读者可以得出调整角度是通过设置m_proj的‘lon’、‘lat’、‘alt’属性值确定的。‘lon’代表视角所在的经度(单位为°),‘lat’代表视角所在的纬度(单位为°),‘alt’代表视角所在的位置到地表的距离(单位为1个地球半径)。

  (2)MATLAB风矢量图可以用quiver、m_quiver和m_vec等函数来绘制,但若要绘制箭头比例尺,需要相等大小矢量的箭头长度相等比例尺才能有意义,因而选m_vec函数。

  (3)通过对例4的实践,读者可以得出想要在继续绘图时保留原痕迹,需要设置‘hold’属性为‘on’,也可以直接执行语句“hold on”实现设定。箭头颜色的设置方法已在1.2节给出。

  (4)绘制海岸线及填充陆地颜色可参考例4,用m_coast函数绘制海岸线,要想填充陆地,里面加上‘patch’加设定的颜色即可实现。难点/拉分点(第1/4个),在于如何把海洋填充为浅蓝色。由于是开卷,读者可以通过到m_map官网中查询gallery中的相关内容得知,可通过设置m_proj里的‘backgroundcolor’属性为淡蓝色将海洋颜色设置为淡蓝色。

  (5)比例尺的位置、标注文本、文字位置、框线颜色、框线宽、填充颜色和透明度的设定详见2.3.2节。难点/拉分点(第2/4个),在于风场比例尺如何紧贴在风异常场比例尺的上方。通过阅读2.3.3节知,读者可通过get函数获取对象的属性名称和属性值,并在mathworks网站上或MATLAB文档中查询相关属性的含义。在使用get函数时,对象的后面再加上属性名称,即可获取相应的属性值,如获取风异常场的位置(‘position’)。而前面2.3.2节也讲过,有4个元素的position各自的含义,只需将第二个元素减去第四个元素,即可得到风场比例尺的位置,然后再用set函数完成对风场比例尺位置的设定。难点/拉分点(第3/4个),如何去掉两个比例尺中间的黑线。这一点考察读者的创新能力,读者可以将其中一个框的框线和填充都去掉,然后用set函数将另一个框包住这两个比例尺,据2.3.3节可得知需要更改属性值的对象是layer而不是ax。

  (6)通过对例1的实践得知用m_grid可绘制出经纬网络。难点/拉分点(第4/4个,是读者想要拿到满分的最大拦路虎),如何将赤道纬线圈标注为“EQ”。这一点考察读者的发散思维能力,因为在查阅了m_map官网后也没有找到解决的办法,需要读者自行手动解决。虽然m_map官网没有直接给出直接标注“EQ”的方法,但是读者通过阅读m_map官网上的其他内容从而受到启发。在使用m_grid画经纬网络时,使用‘ytick’指定不画赤道纬线圈,然后用m_plot画出赤道纬线圈。需要注意的是,线型、线色、线宽需设置得和网格线一模一样,这一点用户可通过打开m_grid.m文件查看代码,搜索‘linewidth’找到代码第107行左右,可查看到默认的线型、线色、线宽等变量名称,然后再分别搜索对应变量名,并查询相应代码,在代码第422行左右可以看到最终画线语句中所使用的关于设定线型、线色的变量名(glinestyle、ggridcolor)和线宽(0.1),综合分析后读者可得知m_grid中线型、线色、线宽的默认值是这样设定的:线型默认为点线‘:’,线色默认为黑色‘k’,线宽则固定为0.1。而对于标注文本‘EQ’的位置,读者可以仿照本文2.3.3节给出的做法,通过让m_plot输出对象,即plt = m_plot,再用get(plt)查看plt的各属性,得知plt所画的格点在图窗中的横纵坐标包含在‘XData’、‘YData’内。而这些数据在开头和结尾都有一段NaN,则图中线的端点坐标对应的是第一个非NaN的坐标。然后读者再用text函数,通过查询mathworks官网得知文字的右对齐为将‘HorizontalAlignment’属性值设为‘right’,从而得以在赤道纬线圈的左端点的左侧标出文本“EQ”。

3 另一种可直接判断风速大小的矢量图——风矢杆图(m_windbarb)

3.1 什么是风矢杆

  风矢杆(wind shaft)由风向杆和风羽组成。若风羽所在的位置为风向杆的顶部,则风向杆的尾端应位于该风所在的地点处,此时风向杆尾端指向的方向为风吹向的方向。而风向是指风的来向,例如风羽在风向杆的南侧,则吹的是南风。风羽可以是由短横线、长横线和三角形组成。当风速>0且≤1 m/s时,只有风杆而无风羽;当风速>1 m/s且≤3 m/s时,在风杆的靠近顶端一截的地方有一根短横线(上面留了一截杆,是为了和风速>3 m/s且≤5 m/s的情况区分),当风速>3 m/s且≤5 m/s,在风杆的顶端有一根长横线。此后每2 m/s一个档,当只有长横线时再在风杆稍靠下的位置处添加一根短横线,当有短横线时短横线变为长横线。直到风速>17 m/s且≤19 m/s时,此时有4根长横线和1根短横线,再到风速>19 m/s且≤21 m/s时五根长横线缩写为三角形。此后每五根长横线缩写为一个三角形。例如,当风速>51 m/s且≤53 m/s时,风羽为两个三角形和三根长横线(如图7所示)。

  关于如何根据风速大小绘制风羽,不同地方也有不同的规定。例如m_map工具包中的m_windbarb的规定是,一根短划线代表5节(knot,1 knot = 463/900 m/s),一根长划线代表10节,一个三角形代表50节等。

图7 风矢杆标法示意

3.2 用m_windbarb画风矢杆图

h = m_windbarb(long, lat, u, v)

h = m_windbarb(long, lat, u, v, Name, Value)

h = m_windbarb(long, lat, u, v, S, Name, Value)

  long、lat分别是坐标的经度、纬度,u、v是风矢量的东分量大小和北分量大小,S是风矢杆的长度(默认为0.9,值越大风矢杆越长,通常无需设定),h为风矢杆图形‘line’对象,用户可通过使用get函数获取其属性值、使用set函数设定其属性值(做法类似于2.3.3节),如设置风矢杆的线宽为1.5:set(h, ‘linewidth‘, 1.5)。

  关于Name-Value(使用方法类似于2.3.2节):

  ①属性名称为’units’,选择u、v值所对应的单位。属性值可设为’knots’、’m/s’、’kmh’、 ‘mph’。’knots’为节(默认),即若u(1) = 3,则u(1)的大小为3节。1节 = 463/900 m/s。’m/s’为米每秒,若将’units’的属性值设定为’m/s’,若u(1) = 3,则u(1)的大小为3 m/s。以此类推。’kmh’为km/h,1 km/h = 5/18 m/s。’mph’为miles per hour,英里/小时,1 mph = 1397/3125 m/s。

  ②同line属性的设定。用户可以在MATLAB文档或者mathworks官网上查询line属性的属性名称和属性值及其含义,这里就不一一列出了。例如,line属性中有’Color’,用户可将其设为黑色,即

  m_windbarb(long, lat, u, v, ‘Color’, ‘k’)

  或者

  h = m_windbarb(long, lat, u, v)

  set(h, ‘Color’, ‘k’)

  特别注意的一点:不管设定的’units’为何值,m_windbarb都会将u、v先换算为对应的节数(knots),然后再进行绘图,且绘制风羽的标准与我们绘制风羽的标准不同

  5节画一短横,10节画一长横,50节画一三角形。

  若用户想用我们绘制风羽的标准绘图,若u、v的实际单位是m/s,在调用m_windbarb时可将’units’仍设置为’knots’,需要操作的是u、v的值都乘以2.5,这样m_windbarb画出的风矢杆就是2 m/s画一短横,4 m/s画一长横,20 m/s画一三角形了(和我们的标准一样了)。

例5 将练习题的风场绘制为风矢杆图,风矢杆颜色为黑色,无需绘制箭头比例尺,其他要求不变。

代码语言:javascript复制
[u, v] = get_data(); %为了看起来整洁,数据的输入放在了后面的函数中
lon = 180 : 5 : 240;
lat = 30 : -5 : -30;
[X, Y] = meshgrid(lon, lat); %X、Y为lon、lat的网格横纵坐标
fig = figure('position', [50, 100, 600, 600]); %创建figure
ax = axes; %创建图窗
m_proj('satellite', 'lon', 210, 'lat', 0, 'alt', 2);        %设置投影图为
%          satellite,观察者角度为EQ、150°W上方距离地表0.6个地球半径的太空中
hold on %保留痕迹,继续绘图
m_coast('patch', [0.5, 0.5, 0.5]); %填充陆地
m_grid('xtick', 180:30:240, 'ytick', [-30, 30], 'backgroundcolor', ...
    [0.45, 0.73, 1], 'xaxislocation', 'middle', 'fontsize', 8) %添加网格,填充海洋
u(1, 4) = -10.9;
HP1 = m_windbarb(X, Y, u * 2.5, v * 2.5, 'units', 'knots', 'color', 'k');
axes(ax);
plt = m_plot(100 : 1 : 300, zeros(1, 201), ':k', 'linewidth', 0.1);
plt_x = get(plt, 'XData');
plt_y = get(plt, 'YData');
pos = find(~ isnan(plt_x));
text(plt_x(pos(1)), plt_y(pos(1)), 'EQ', 'HorizontalAlignment', 'right', ...
    'VerticalAlignment', 'middle', 'fontsize', 8, 'color', 'k')
set(gcf, 'color', 'w')
function [u, v] = get_data()
u = [-3.45,-5.89,-9.08,-10.49,-9.52,-7.03,-5.11,-4.17,-2.91,-1.34,0.81,2.68,3.73;
-2.81,-2.76,-4.82,-7.30,-8.66,-9.11,-9.01,-7.48,-5.78,-5.26,-4.44,-3.79,-1.01;
-3.14,-2.58,-3.51,-5.62,-5.76,-5.50,-7.45,-7.97,-7.02,-6.86,-6.38,-6.34,-5.27;
-5.17,-4.31,-3.85,-5.77,-7.54,-7.01,-7.08,-7.38,-6.98,-7.66,-8.70,-8.41,-7.98;
-5.63,-5.12,-4.90,-4.97,-5.58,-5.13,-5.32,-7.31,-8.33,-7.53,-5.56,-3.63,-3.32;
-5.24,-4.74,-5.48,-6.19,-6.59,-6.63,-6.75,-7.10,-6.76,-5.71,-4.33,-3.55,-2.24;
-6.49,-7.33,-8.15,-8.39,-8.89,-10.46,-10.77,-9.09,-7.48,-6.47,-7.07,-7.48,-6.54;
-5.06,-5.99,-6.76,-7.28,-7.68,-8.94,-9.06,-7.80,-7.67,-7.07,-7.66,-7.72,-7.69;
-3.09,-4.08,-4.67,-5.41,-5.48,-4.96,-5.38,-5.89,-6.42,-6.65,-7.64,-8.72,-9.71;
-3.62,-3.93,-3.88,-3.70,-4.54,-4.50,-4.61,-5.24,-6.09,-7.17,-6.99,-6.95,-7.91;
-5.31,-4.89,-4.96,-4.32,-4.75,-5.36,-4.71,-3.82,-4.12,-5.17,-5.70,-5.46,-5.37;
-4.98,-4.77,-5.13,-5.54,-5.03,-4.04,-3.40,-3.30,-3.73,-3.97,-5.18,-5.51,-5.43;
-4.33,-4.68,-4.99,-6.15,-6.30,-5.19,-4.08,-3.31,-3.71,-4.54,-5.23,-4.61,-4.24];
v = [-4.30,-1.27,1.64,1.66,0.10,-0.81,-1.46,-2.21,-2.81,-2.66,-1.92,-2.44,-3.03;
-4.54,-1.39,1.35,1.83,0.09,-0.95,-1.36,-2.45,-2.90,-2.94,-2.68,-2.84,-3.58;
-3.28,-1.45,0.40,1.79,-0.01,-1.52,-0.77,-2.27,-3.59,-3.48,-3.52,-3.63,-3.91;
-2.75,-1.92,-0.62,1.11,0.11,-1.54,-1.29,-2.92,-4.29,-3.56,-3.05,-2.97,-3.05;
-2.76,-1.60,-0.43,0.12,0.39,0.10,-2.23,-3.74,-3.59,-2.28,-0.23,1.08,-0.19;
0.07,0.65,1.60,1.68,2.63,2.58,-2.12,-3.20,-1.48,0.60,3.49,4.81,2.55;
-0.22,0.01,0.55,0.68,1.73,1.49,-1.12,-1.49,-0.49,1.33,3.24,3.98,2.99;
-2.86,-2.08,-1.65,-1.24,-1.35,-2.01,-0.69,-0.37,-0.21,1.37,2.22,3.09,3.00;
-2.60,-2.09,-1.83,-1.22,-1.79,-2.04,-0.23,0.23,0.26,0.92,0.55,1.23,1.96;
-2.11,-1.33,-1.22,-1.60,-1.54,-0.64,-0.76,-0.61,-0.82,-0.13,0.25,-0.58,-0.43;
-1.02,0.41,0.56,-0.22,-1.44,-0.53,-0.06,-0.24,-1.51,-1.32,-0.17,-0.71,-2.64;
-0.67,-0.05,0.64,1.39,-0.13,0.09,0.84,-0.34,-1.79,-1.97,-1.21,0.86,-2.55;
-0.74,-1.15,-0.91,0.17,1.26,1.79,1.73,0.84,-0.71,-1.72,-1.97,0.40,-1.60];
end

图9 不用箭头比例尺依然知道风速大小大致值的图——风矢杆图

4 总结与讨论

  MATLAB具有运算速度快、功能强大、实时编程、人机对话友好等特点,然而美中不足的是无法在图窗外绘制矢量图的箭头比例尺。而在地图放大系数因地变化的投影图中,m_quiver画出的箭头长度除了受矢量大小本身的影响外,还受到地图放大系数的影响,因而较难采用箭头比例尺。但m_vec函数恰克服了这一点,其所画的箭头长度仅与矢量大小有关,因而箭头比例尺可基于用m_vec绘制的矢量图进行绘制。此外,本人又开发了可专门为m_vec绘制的矢量图在Figure内任意位置添加箭头比例尺的函数m_arrow_scale2,本人认为该函数考虑了方方面面,如文本标注、位置、字体等参数,且都有多个已给出的参数供使用者选择,选择的余地非常多,使用起来非常方便,功能也较为强大。而想要绘制出可以看出矢量大小的矢量图,除了在旁边标出箭头比例尺外,还可以采用风矢杆图,用m_windbarb进行绘制。但该函数采用的标准不同,是5节画一短横,而我们的标准是2 m/s画一短横,使用时需要注意,画图时可将单位设为节、速度乘以2.5以适应我们的标准。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/153470.html原文链接:https://javaforall.cn

0 人点赞