⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_vec.m

📁 A mapping package for Matlab:这是一款功能十分强大的地理绘图工具包
💻 M
字号:
function [hp, ht] = mvec(s, x, y, varargin)  % and color, etc% M_VEC Draws fancy arrows/quiverplots on a map.%    [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.%      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.%%  Mon  98/02/16 Eric Firing, efiring@soest.hawaii.edu%% 6/Nov/00 - eliminate returned stuff if ';' neglected (thx to D Byrne)% 2/May/01 - small bug fix (thx to Pierre Jaccard)% 7/jun/06 - arrows near boundaries were not done correctly - now fixed.global MAP_PROJECTION% Have to have initialized a map firstif nargin==0,  % demo    % demvec.m    % This is a demonstration of m_vec.    % Sun  98/02/22 Eric Firing    % Set up the figure and axes at the start, so that the vector lengths    % will come out right when the figure is printed:    orient tall    % Main axes, for the map.    ha1 = axes;    pos = get(ha1,'position');    pos1 = pos;    pos1(4) = pos1(4) - 0.1;    pos1(2) = pos1(2) + 0.1;    set(ha1,'position',pos1)    % Colormap axes.  Make them smaller than for the default colormap.    pos2 = [0.3  0  0.4  0];    pos2(2) = pos(2);    pos2(4) = 0.02;    % This positioning of the colormap is actually not very good as    % printed, but I am not going to fiddle with it any more now.    % This is just a typical difficulty with normalized coordinates    % combined with fixed DataAspectRatio; if    % something looks reasonable on the screen, it is likely to look    % wrong when printed.    ha2 = axes('position', pos2);    axes(ha1); % Back to the main axes.    m_proj('ortho','lat',48','long',-123', 'rad', 10, ...        	'rec', 'off' );    m_coast('patch',[0.9 0.95 0.9]);    m_grid('linest','-','xtick',[-135:5:-110]);    title('Demonstration of m\_vec')    %% The following form, centered and without heads, is suitable for    %% the square roots of the principle axes of variance ellipses,    %% for example.  Color is given as a single RGB triplet; if it were    %% given as an array of triplets, the two lines could be different    %% colors; unfortunately, as of Matlab 5.1, if you do this the plot    %% will be forced into Zbuffer mode with the warning:    %%  "RGB color data not yet supported in Painter's mode"    %% This example also illustrates specification of a black patch    %% boundary, via direct patch property specifications following any    %% vector parameter options.    hpv1 = m_vec(100, [-133 -133], [49 49], [0 50], [100 0.0],...	  [0.7 0.8 0.9],'centered','yes', ...	  'shaftwidth', 5, 'headlength', 0,...	  'EdgeColor','k');    %% Here are three vectors, no color specified, all properties defaulted.    hpv2 = m_vec(100, [-128 -128 -128], [46 46 46], ...     [0 25*sqrt(2) 50], [50 25*sqrt(2) 0]);    incs = (1:20)/20;    vlat = 42 + incs*3;    vlon = -127 - incs*2;    uu = 50*sin(incs*2*pi);    vv = 50*cos(incs*2*pi);    %% This simulates a set of vectors such as currents measured    %% with an ADCP along a cruise track.  Color is specified by letter,    %% in this case. The arrows and heads are about as skinny as they    %% can reasonably be.    hpv3 = m_vec(100, vlon, vlat, uu, vv, 'm', ...     'shaftwidth', 0.2, 'headlength', 2.5);    %% Now let's make a similar vectors, but with colors based on the    %% colormap, simulating SST, for example:    vlon = vlon - 3;    sst = 12 - incs * 4;    hpv4 = m_vec(100, vlon, vlat, uu, vv, sst);    colorbar(ha2);    axes(ha2); xlabel('SST'); axes(ha1);    %% These vectors will not show up well on the screen because they    %% have no edges, but they will print adequately.  There does not    %% seem to be any easy way to get around this; I would have to    %% completely change the way the patches are specified.  Ordinarily,    %% one would probably use fatter than default vectors with this    %% method anyway, so that the colors are clear when printed; and in    %% this case the screen display will look OK also.    %% Key: Note that it can be on or off the map. The vector and    %% text are the same color by default. Handles to both the vector    %% (patch) and the label (text) are returned so that you can    %% change the font, color, etc.    [hpv5, htv5] = m_vec(100, -115, 38, 50, 0, 'b', 'key', '50 cm s^{-1}');    set(htv5,'FontSize',8);    returnendif isempty(MAP_PROJECTION),  error('No Map Projection initialized - call M_PROJ first!');end;% Default arrow parameters:centered = 0;headlength = 5/72;headwidth  = NaN;headangle = 40;shaftwidth = 1/72;c = 'k';key = '';clip = 'on'; % except for the keyif nargin < 5,   % Minimum: s,x,y,u,v   help('mvec');   error('not enough input arguments');endUVperIn = s;x = x(:);y = y(:);%% Begin the slightly complicated parsing of arguments.  This%% could probably be done more efficiently and elegantly.% One cause of complexity is that the optional argument c% could be either character or numeric.keyvars = {};  % This will hold keyword/value pairs.nvarargin = length(varargin);% Find the index of the first string argument in varargin.istr0 = 0;for ii = 1:nvarargin   if ischar(varargin{ii}), istr0 = ii; break, endendif istr0 > 0,    % There are strings.   if rem(nvarargin - istr0, 2) == 0,  % an odd number      c = varargin{istr0}; % should be a colorspec string      istr0 = istr0 + 1;   end   % istr0: start of keyword/value pairs.   n_numeric = istr0 - 1;  %Actually, numeric or colorspec.   keyvars = varargin(istr0:nvarargin);   finished = 0;   while ~isempty(keyvars) & ~finished,      kv = lower(keyvars{1});      value = keyvars{2};      if     strcmp(kv, 'headlength')         headlength = value/72;      elseif strcmp(kv, 'headwidth')         headwidth = value/72;      elseif strcmp(kv, 'headangle')         headangle = value;      elseif strcmp(kv, 'shaftwidth')         shaftwidth = value/72;      elseif strcmp(kv, 'centered')  & lower(value(1)) == 'y',         centered = 1;      elseif strcmp(kv, 'key')         key = value;         clip = 'off'; % Can put key outside the map.      else         finished = 1;  % no match; break out      end      if ~finished,         keyvars(1:2) = [];      end   endelse   n_numeric = nvarargin;end% Calculate the headwidth if it is not given explicitly:if isnan(headwidth) & headangle < 170 & headangle > 0   headwidth = headlength * tan(headangle*pi/180);endheadwidth = max([headwidth; shaftwidth]);if n_numeric == 2 | n_numeric == 3,   u = varargin{1}(:);   v = varargin{2}(:);   if n_numeric == 3,      c = varargin{3};   end   z = zeros(size(u));elseif n_numeric == 4,   z = varargin{1}(:);   u = varargin{2}(:);   v = varargin{3}(:);   c = varargin{4};else   help('mvec')   error('not enough numeric arguments')end[nr,nc] = size(c);if nr == 1 & nc == length(u) & (nc ~= 3 | (any(c<=1) | any(c>=0))),   c = c(:);end% c could be a 1x3 colorspecif (length(x) == 1 & length(y) == 1 & length(u) > 1)   x = x(ones(size(u)));   y = y(ones(size(u)));end%% End of input argument parsing.OrigAxUnits = get(gca,'Units');if OrigAxUnits(1:3) == 'nor'   OrigPaUnits = get(gcf, 'paperunits');   set(gcf, 'paperunits', 'inches');   figposInches = get(gcf, 'paperposition');   set(gcf, 'paperunits', OrigPaUnits);   axposNor = get(gca, 'position');   axWidLenInches = axposNor(3:4) .* figposInches(3:4);else   set(gca, 'units', 'inches');   axposInches = get(gca, 'position');   set(gca, 'units', OrigAxUnits);   axWidLenInches = axposInches(3:4);end% Multiply inches by the following to get data units:scX = diff(get(gca, 'XLim'))/axWidLenInches(1);scY = diff(get(gca, 'YLim'))/axWidLenInches(2);sc = max([scX;scY]);  %max selects the dimension limited by                      % the plot box.Width = shaftwidth*sc;HeadWidth = headwidth*sc;HeadLength = headlength*sc;uvmag = abs(u + i*v);% Arrow lengths in plot data units:L = uvmag*sc/UVperIn;% base of arrows. Don't plot if outside boundaries (except for keys for which clip is off)[xs, ys] = m_ll2xy(x,y, 'clip', clip);%[xsp, ysp] = m_ll2xy(x+0.1*u./uvmag, y+0.1*v.*cos(y*pi/180)./uvmag, 'clip', clip);% Vector angles in the Cartesian data-unit system of m_map:%Ang = angle( (xsp-xs) + i*(ysp-ys) );% ABove angle calc could fail when arrows were near boundaries. Replace with this.% Now we calculate angles. Use a small offset, and keep clipping off to prevent odd things% happening.%    - RP 7/Jun/06[xsp, ysp] = m_ll2xy([x x+0.00001*u./uvmag]',[y y+0.00001*v.*cos(y*pi/180)./uvmag]' , 'clip', 'off');Ang = angle( diff(xsp)' + i*diff(ysp)' );if ~isempty(key), Ang = 0; endnvec = length(L);Zero = zeros(nvec,1);One  = ones(nvec,1);% Normal arrow dimensions:HL = Zero+HeadLength;HW = Zero+HeadWidth;W =  Zero+Width;% Distinguish zero-length vectors from non-zero:mm = (L < 100*eps);i_zero = find(mm);i_nonzero = find(~mm);% Don't plot if length is zero.if ~isempty(i_zero)   HL(i_zero) = NaN; HW(i_zero) = NaN; W(i_zero) = NaN;endif ~isempty(i_nonzero)   ii = i_nonzero;   if HeadLength == 0,   %% square end; no arrowhead      W(ii)  = Width;      HW(ii) = Width;      HL(ii) = Zero(ii);  % Thanks for Pierre Jaccard for this fix   else      % If the arrow length is less than the headlength,      % omit the arrow shaft and just plot a head scaled      % to the length.      i_short = ii( find(L(ii) < HeadLength) );      W(i_short)  = 0;      HL(i_short) = L(i_short);      HW(i_short) = HL(i_short) * (HeadWidth/HeadLength);   endend% Just a change of variable names for historical reasons:Y = ys;X = xs;% It is not clear whether non-zero elevations will be useful;% that depends on whether the entire m_map system will work% with 3-D views, as in making a surface plot of topography.% Then one might want to have a current profile represented% as a stack of vectors at appropriate heights above the topog.Z = z(:);Xzero = Zero;if centered,   Xzero = -L/2;endnV = 7*nvec;  % number of Vertices: 7 per arrow.Vert = zeros(nvec,3);Vert(1:7:nV,:) =  [Xzero,  W/2, Z ];       % back corner of shaftVert(2:7:nV,:) = Vert(1:7:nV,:) + ...                 [(L-HL), Zero,  Zero];    % shaft-head junctionVert(3:7:nV,:) = Vert(2:7:nV,:) + ...                 [Zero, (HW-W)/2,  Zero];  % point of barbVert(4:7:nV,:) = [Xzero + L, Zero, Z];     % tip of arrow%% This could be done more efficiently with fancier indexing, but%% it is probably not a bottleneck, hence not worth the trouble.% Reflect the top half to get the bottom half.% First replicate:Vert(5:7:nV,:) = Vert(3:7:nV,:);Vert(6:7:nV,:) = Vert(2:7:nV,:);Vert(7:7:nV,:) = Vert(1:7:nV,:);% Then negate y to reflect:Vert(5:7:nV,2) = -Vert(5:7:nV,2);Vert(6:7:nV,2) = -Vert(6:7:nV,2);Vert(7:7:nV,2) = -Vert(7:7:nV,2);% Make an index array for operating on all vertices of each vector:ii = (1:nvec);ii = ii(ones(7,1),:);ii = ii(:);%% Rotate:Vxy = exp(i*Ang(ii)).*(Vert(:,1) + i*Vert(:,2));%% Translate:Vxy = Vxy + X(ii) + i*Y(ii);%%Vert(:,1) = real(Vxy);Vert(:,2) = imag(Vxy);Faces = [1:nV].';            %TopFaces = reshape(Faces,7,nvec).';% Extremely narrow patches don't show up on the screen (although they seem% to be printed OK) when EdgeColor is 'none', so when the arrows are all% the same color, set the EdgeColor to be the same as FaceColor.% Set clip off here so arrows are complete - RP 7/Jun/06hp = patch('Faces', Faces, 'Vertices', Vert, 'tag', 'm_vec','clip','off');if ischar(c) | (size(c,1) == 1 & size(c,2) == 3),   set(hp, 'EdgeColor', c, 'FaceColor', c, 'LineWidth', 0.1);else   set(hp, 'EdgeColor', 'none', 'FaceColor','Flat', ...     'FaceVertexCdata', c);endif ~isempty(keyvars)   set(hp, keyvars{:});endif ~isempty(key)   ht = text(X(1), Y(1)-0.5*HW, Z(1), key, ...      'color', c, 'horiz','left','vert','top', 'tag','m_vec', ...      'clipping','off');   set(hp,'clipping','off')else   ht = [];endif nargout==0  clear hp htend;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -