PLOTTRANSECTCURRENTMAP Plot map of glider trajectory with waypoints and current estimates. Syntax: PLOTTRANSECTCURRENTMAP(OPTIONS) PLOTTRANSECTCURRENTMAP(OPT1, VAL1, ...) PLOTTRANSECTCURRENTMAP(H, OPTIONS) PLOTTRANSECTCURRENTMAP(H, OPT1, VAL1, ...) [HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, HCUR] = PLOTTRANSECTCURRENTMAP(...) Description: PLOTTRANSECTCURRENTMAP(OPTIONS) and PLOTTRANSECTCURRENTMAP(OPT1, VAL1, ...) generate a new figure with a line plot of the trajectory described in glider data over a map, with an optional line plot of the waypoint path and a vector plot of the estimated average currents, according to options in key-value pairs OPT1, VAL1... or in struct OPTIONS with field names as option keys and field values as option values. The map is generated with M_PROJ, M_PATCH and M_GSHHS_H or M_USERCOAST. The line plots are generated with M_PLOT, and the vector plot with M_VEC. Recognized options are: LATDATA: trajectory latitude coordinate data. Vector to use as latitude coordinate of the glider trajectory. Default value: [] LONDATA: trajectory longitude coordinate data. Vector to use as longitude coordindate of the glider trajectory. Default value: [] WPTLATDATA: waypoint path latitude data. Vector to use as latitude coordinates of the waypoint path. Default value: [] WPTLONDATA: waypoint path longitude data. Vector to use as longitude coordinates of the waypoint path. Default value: [] CURNORDATA: northward current data. Vector to use as northward component of water velocity estimates. Default value: [] CUREASDATA: eastward current data. Vector to use as eastward component of water velocity estimates. Default value: [] CURSCALE: current unit scale. Scalar specifying the length of current vectors in inches. Default value: 1 COASTFILE: precomputed coast line data file. String with the path to the coast file to be passed to function M_USERCOAST to generate the land patch. If empty, M_GSHHS_H is called instead. Default value: [] (call M_GSHHS_H) XLABEL: horizontal axis label data. Struct defining x label properties. The text of the label is in property 'String'. Default value: struct() YLABEL: vertical axis label data. Struct defining y label properties. The text of the label is in property 'String'. Default value: struct() CLABEL: color bar label data. Struct defining color bar label properties. The text of the label is in property 'String'. Actually this will be the colorbar's child object 'Title'. Default value: struct() TITLE: axes title data. Struct defining axes title properties. The text of the label is in property 'String'. Default value: struct() AXSPROPS: extra axis properties. Struct of axis properties to set for the plot axes with function SET. Default value: struct() FIGPROPS: extra figure properties. Struct of figure properties to set for the figure with function SET. Default value: struct() PLOTTRANSECTCURRENTMAP(H, ...) does not create a new figure, but plots to figure given by figure handle H. [HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, HCUR] = PLOTTRANSECTCURRENTMAP(...) returns handles for the figure, axes, legend, color bar, lines and patch objects in HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, and HCUR respectively. Notes: This function requires the files from the Global Self-consistant Hierarchical High-resolution Shorelines data suite (GSHHS) to be available in the path when no user defined coast file is provided. Please see installation details in M_Map official site: <http://www.eos.ubc.ca/~rich/private/mapug.html#p9.5> The map is plotted in the geographic coordinate system (longitude-latitude, no projection) and the map boundaries are selected such that the resulting map fills the given plot box with a data aspect ratio of 1. Water velocity estimates are represented as colored normalized vectors with the magitude value (absolute water speed) as color coordinate. The vectors are scaled so that they length matches the desired length given in inches. Examples: [hfig, haxs, hlgn, hcba, htrj, hwpt, hcur] = ... plotTransectCurrentMap(gcf, ... 'latdata', linspace(39, 40, 30) - [0 5.0/60*rand(1,29)], ... 'londata', linspace( 0, 2, 30) - [0 2.5/60*rand(1,29)], ... 'wptlatdata', [39 40], 'wptlondata', [0 2], ... 'curnordata', -10 + 5 * rand(1, 30), ... 'cureasdata', -5 + 5 * rand(1, 30), ... 'curscale', 0.25, ... 'title', struct('String', 'Random trajectory and current plot'), ... 'xlabel', struct('String', 'longitude'), ... 'ylabel', struct('String', 'latitude'), ... 'clabel', struct('String', 'depth-averaged current (m s-1)'), ... 'axsprops', struct('Layer', 'top', 'XGrid', 'on', 'Ygrid', 'on'), ... 'figprops', struct('Name', 'Trajectory and current map', ... 'PaperPosition', [0 0 8.3 6.6], ... 'PaperUnits', 'inches')) See also: M_PROJ M_GSHHS_H M_USERCOAST M_VEC M_PLOT SET Authors: Joan Pau Beltran <joanpau.beltran@socib.cat>
0001 function [hfig, haxs, hlgn, hcba, htrj, hbeg, hend, hwpt, hcur] = plotTransectCurrentMap(varargin) 0002 %PLOTTRANSECTCURRENTMAP Plot map of glider trajectory with waypoints and current estimates. 0003 % 0004 % Syntax: 0005 % PLOTTRANSECTCURRENTMAP(OPTIONS) 0006 % PLOTTRANSECTCURRENTMAP(OPT1, VAL1, ...) 0007 % PLOTTRANSECTCURRENTMAP(H, OPTIONS) 0008 % PLOTTRANSECTCURRENTMAP(H, OPT1, VAL1, ...) 0009 % [HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, HCUR] = PLOTTRANSECTCURRENTMAP(...) 0010 % 0011 % Description: 0012 % PLOTTRANSECTCURRENTMAP(OPTIONS) and 0013 % PLOTTRANSECTCURRENTMAP(OPT1, VAL1, ...) generate a new figure with a line 0014 % plot of the trajectory described in glider data over a map, with an 0015 % optional line plot of the waypoint path and a vector plot of the estimated 0016 % average currents, according to options in key-value pairs OPT1, VAL1... 0017 % or in struct OPTIONS with field names as option keys and field values as 0018 % option values. The map is generated with M_PROJ, M_PATCH and M_GSHHS_H or 0019 % M_USERCOAST. The line plots are generated with M_PLOT, and the vector plot 0020 % with M_VEC. Recognized options are: 0021 % LATDATA: trajectory latitude coordinate data. 0022 % Vector to use as latitude coordinate of the glider trajectory. 0023 % Default value: [] 0024 % LONDATA: trajectory longitude coordinate data. 0025 % Vector to use as longitude coordindate of the glider trajectory. 0026 % Default value: [] 0027 % WPTLATDATA: waypoint path latitude data. 0028 % Vector to use as latitude coordinates of the waypoint path. 0029 % Default value: [] 0030 % WPTLONDATA: waypoint path longitude data. 0031 % Vector to use as longitude coordinates of the waypoint path. 0032 % Default value: [] 0033 % CURNORDATA: northward current data. 0034 % Vector to use as northward component of water velocity estimates. 0035 % Default value: [] 0036 % CUREASDATA: eastward current data. 0037 % Vector to use as eastward component of water velocity estimates. 0038 % Default value: [] 0039 % CURSCALE: current unit scale. 0040 % Scalar specifying the length of current vectors in inches. 0041 % Default value: 1 0042 % COASTFILE: precomputed coast line data file. 0043 % String with the path to the coast file to be passed to function 0044 % M_USERCOAST to generate the land patch. If empty, M_GSHHS_H is called 0045 % instead. 0046 % Default value: [] (call M_GSHHS_H) 0047 % XLABEL: horizontal axis label data. 0048 % Struct defining x label properties. 0049 % The text of the label is in property 'String'. 0050 % Default value: struct() 0051 % YLABEL: vertical axis label data. 0052 % Struct defining y label properties. 0053 % The text of the label is in property 'String'. 0054 % Default value: struct() 0055 % CLABEL: color bar label data. 0056 % Struct defining color bar label properties. 0057 % The text of the label is in property 'String'. 0058 % Actually this will be the colorbar's child object 'Title'. 0059 % Default value: struct() 0060 % TITLE: axes title data. 0061 % Struct defining axes title properties. 0062 % The text of the label is in property 'String'. 0063 % Default value: struct() 0064 % AXSPROPS: extra axis properties. 0065 % Struct of axis properties to set for the plot axes with function SET. 0066 % Default value: struct() 0067 % FIGPROPS: extra figure properties. 0068 % Struct of figure properties to set for the figure with function SET. 0069 % Default value: struct() 0070 % 0071 % PLOTTRANSECTCURRENTMAP(H, ...) does not create a new figure, but plots 0072 % to figure given by figure handle H. 0073 % 0074 % [HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, HCUR] = PLOTTRANSECTCURRENTMAP(...) 0075 % returns handles for the figure, axes, legend, color bar, lines and patch 0076 % objects in HFIG, HAXS, HLGN, HCBA, HTRJ, HBEG, HEND, HWPT, and HCUR 0077 % respectively. 0078 % 0079 % Notes: 0080 % This function requires the files from the Global Self-consistant 0081 % Hierarchical High-resolution Shorelines data suite (GSHHS) to be available 0082 % in the path when no user defined coast file is provided. Please see 0083 % installation details in M_Map official site: 0084 % <http://www.eos.ubc.ca/~rich/private/mapug.html#p9.5> 0085 % 0086 % The map is plotted in the geographic coordinate system (longitude-latitude, 0087 % no projection) and the map boundaries are selected such that the resulting 0088 % map fills the given plot box with a data aspect ratio of 1. 0089 % 0090 % Water velocity estimates are represented as colored normalized vectors with 0091 % the magitude value (absolute water speed) as color coordinate. The vectors 0092 % are scaled so that they length matches the desired length given in inches. 0093 % 0094 % Examples: 0095 % [hfig, haxs, hlgn, hcba, htrj, hwpt, hcur] = ... 0096 % plotTransectCurrentMap(gcf, ... 0097 % 'latdata', linspace(39, 40, 30) - [0 5.0/60*rand(1,29)], ... 0098 % 'londata', linspace( 0, 2, 30) - [0 2.5/60*rand(1,29)], ... 0099 % 'wptlatdata', [39 40], 'wptlondata', [0 2], ... 0100 % 'curnordata', -10 + 5 * rand(1, 30), ... 0101 % 'cureasdata', -5 + 5 * rand(1, 30), ... 0102 % 'curscale', 0.25, ... 0103 % 'title', struct('String', 'Random trajectory and current plot'), ... 0104 % 'xlabel', struct('String', 'longitude'), ... 0105 % 'ylabel', struct('String', 'latitude'), ... 0106 % 'clabel', struct('String', 'depth-averaged current (m s-1)'), ... 0107 % 'axsprops', struct('Layer', 'top', 'XGrid', 'on', 'Ygrid', 'on'), ... 0108 % 'figprops', struct('Name', 'Trajectory and current map', ... 0109 % 'PaperPosition', [0 0 8.3 6.6], ... 0110 % 'PaperUnits', 'inches')) 0111 % 0112 % See also: 0113 % M_PROJ 0114 % M_GSHHS_H 0115 % M_USERCOAST 0116 % M_VEC 0117 % M_PLOT 0118 % SET 0119 % 0120 % Authors: 0121 % Joan Pau Beltran <joanpau.beltran@socib.cat> 0122 0123 % Copyright (C) 2013-2016 0124 % ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears 0125 % <http://www.socib.es> 0126 % 0127 % This program is free software: you can redistribute it and/or modify 0128 % it under the terms of the GNU General Public License as published by 0129 % the Free Software Foundation, either version 3 of the License, or 0130 % (at your option) any later version. 0131 % 0132 % This program is distributed in the hope that it will be useful, 0133 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0134 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0135 % GNU General Public License for more details. 0136 % 0137 % You should have received a copy of the GNU General Public License 0138 % along with this program. If not, see <http://www.gnu.org/licenses/>. 0139 0140 % No argument number checking since any number of arguments is allowed. 0141 0142 %% Set plot options and default values. 0143 options = struct(); 0144 options.latdata = []; 0145 options.londata = []; 0146 options.wptlatdata = []; 0147 options.wptlondata = []; 0148 options.curnordata = []; 0149 options.cureasdata = []; 0150 options.curscale = 1; 0151 options.coastfile = []; 0152 options.xlabel = struct(); 0153 options.ylabel = struct(); 0154 options.clabel = struct(); 0155 options.title = struct(); 0156 options.axsprops = struct(); 0157 options.figprops = struct(); 0158 0159 0160 %% Get optional figure handle and option arguments. 0161 if (nargin > 0) && isscalar(varargin{1}) && ishghandle(varargin{1}) 0162 args = varargin(2:end); 0163 hfig = figure(varargin{1}); 0164 else 0165 args = varargin; 0166 hfig = figure(); 0167 end 0168 0169 0170 %% Get options from extra arguments. 0171 % Parse option key-value pairs in any accepted call signature. 0172 if isscalar(args) && isstruct(args{1}) 0173 % Options passed as a single option struct argument: 0174 % field names are option keys and field values are option values. 0175 option_key_list = fieldnames(args{1}); 0176 option_val_list = struct2cell(args{1}); 0177 elseif mod(numel(args), 2) == 0 0178 % Options passed as key-value argument pairs. 0179 option_key_list = args(1:2:end); 0180 option_val_list = args(2:2:end); 0181 else 0182 error('glider_toolbox:plotTransectCurrentMap:InvalidOptions', ... 0183 'Invalid optional arguments (neither key-value pairs nor struct).'); 0184 end 0185 % Overwrite default options with values given in extra arguments. 0186 for opt_idx = 1:numel(option_key_list) 0187 opt = lower(option_key_list{opt_idx}); 0188 val = option_val_list{opt_idx}; 0189 if isfield(options, opt) 0190 options.(opt) = val; 0191 else 0192 error('glider_toolbox:plotTransectCurrentMap:InvalidOption', ... 0193 'Invalid option: %s.', opt); 0194 end 0195 end 0196 0197 0198 %% Set figure properties. 0199 set(hfig, options.figprops); 0200 0201 0202 %% Initialize axis plot elements. 0203 haxs = gca(); 0204 haxs_hold = ishold(haxs); 0205 if ~haxs_hold 0206 newplot(haxs); 0207 hold(haxs, 'on'); 0208 end 0209 haxstit = title(haxs, []); 0210 haxsxlb = xlabel(haxs, []); 0211 haxsylb = ylabel(haxs, []); 0212 hlgn = []; 0213 hcba = colorbar('SouthOutside'); 0214 hcbatit = get(hcba, 'XLabel'); 0215 set(haxs, options.axsprops); 0216 set(haxstit, options.title); 0217 set(haxsxlb, options.xlabel); 0218 set(haxsylb, options.ylabel); 0219 set(hcbatit, options.clabel); 0220 0221 0222 %% Plot the map. 0223 % Compute axis limits such that data aspect ratio is 1 with axes' current 0224 % position, and glider trajectory is centered in the plot. 0225 lat_bounds = [min(options.latdata) max(options.latdata)]; 0226 lon_bounds = [min(options.londata) max(options.londata)]; 0227 if (numel(lat_bounds) ~= 2) || (max(abs(lat_bounds)) > 90) 0228 lat_bounds = [-90 90]; % arbitrary value when bad latitude data. 0229 end 0230 if (numel(lon_bounds) ~= 2) || (max(abs(lat_bounds)) > 180) 0231 lon_bounds = [-180 180]; % arbitrary value when bad longitude data. 0232 end 0233 max_range = 1.1 * max(diff(lat_bounds), diff(lon_bounds)); 0234 if strcmpi(get(haxs, 'Units'), 'normalized') 0235 set(haxs, 'Units', 'inches'); 0236 haxs_position = get(haxs, 'Position'); 0237 set(haxs, 'Units', 'normalized'); 0238 else 0239 haxs_position = get(haxs, 'Position'); 0240 end 0241 axs_ratio = haxs_position(4) / haxs_position(3); 0242 if axs_ratio < 1 0243 lat_range = max_range; 0244 lon_range = max_range / axs_ratio; 0245 else 0246 lat_range = max_range * axs_ratio; 0247 lon_range = max_range; 0248 end 0249 lat_lims = mean(lat_bounds) + [-0.5 0.5] * lat_range; 0250 lon_lims = mean(lon_bounds) + [-0.5 0.5] * lon_range; 0251 % Set no projection (map coordinates are longitude and latitude). 0252 m_proj('Equidistant Cylindrical', 'lat', lat_lims, 'lon', lon_lims); 0253 % Plot ocean and land as patches without coast lines. 0254 land_color = [1 1 1]; 0255 ocean_color = [0.4141 0.6328 0.7852]; 0256 m_patch(lon_lims([1 1 2 2]), lat_lims([1 2 2 1]), ocean_color, ... 0257 'EdgeColor', 'none'); 0258 if isempty(options.coastfile) 0259 m_gshhs_h('patch', land_color, 'EdgeColor', 'none'); 0260 else 0261 m_usercoast(options.coastfile, 'patch', land_color, 'EdgeColor', 'none') 0262 end 0263 % Remove extra axis limit space and set latitude and longitude ticks. 0264 % This is usually done by calling M_GRID, but it may shrink the axes too much. 0265 % Use the following code as an alternative. 0266 % m_grid('box', 'on', 'backcolor', ocean_color); 0267 [haxs_xlims, haxs_ylims] = m_ll2xy(lon_lims, lat_lims, 'clip', 'off'); 0268 set(haxs, 'XLim', haxs_xlims, 'YLim', haxs_ylims); 0269 0270 lat_tick_step = (10/2) ... 0271 * (floor((2/10) * 10 .^ mod(log10(diff(lat_lims)), 1)) + 1) ... 0272 * 10 .^ (floor(log10(diff(lat_lims))) - 1); 0273 lon_tick_step = (10/2) ... 0274 * (floor((2/10) * 10 .^ mod(log10(diff(lon_lims)), 1)) + 1) ... 0275 * 10 .^ (floor(log10(diff(lon_lims))) - 1); 0276 lat_ticks = (-200 : lat_tick_step : 200); 0277 lon_ticks = (-100 : lon_tick_step : 100); 0278 lat_ticks = lat_ticks(lat_lims(1) <= lat_ticks & lat_ticks <= lat_lims(2)); 0279 lon_ticks = lon_ticks(lon_lims(1) <= lon_ticks & lon_ticks <= lon_lims(2)); 0280 haxs_xticks = ... 0281 haxs_xlims(1) + (lon_ticks - lon_lims(1)) * diff(haxs_xlims) / diff(lon_lims); 0282 haxs_yticks = ... 0283 haxs_ylims(1) + (lat_ticks - lat_lims(1)) * diff(haxs_ylims) / diff(lat_lims); 0284 set(haxs, 'XTick', haxs_xticks, 'XTickLabel', cellstr(num2str(lon_ticks(:)))); 0285 set(haxs, 'YTick', haxs_yticks, 'YTickLabel', cellstr(num2str(lat_ticks(:)))); 0286 0287 0288 %% Plot glider data elements. 0289 % Plot sea water velocity vector estimates. 0290 % Plot normalized vectors with magnitude information in color coordinate. 0291 % The inverse of the scale factor is the size of a unary vector. 0292 if isempty(options.curnordata) || isempty(options.cureasdata) 0293 hcur = []; 0294 else 0295 curabsdata = sqrt(options.curnordata .^ 2 + options.cureasdata .^ 2); 0296 hcur = m_vec(1/options.curscale, options.londata, options.latdata, ... 0297 options.cureasdata ./ curabsdata, ... 0298 options.curnordata ./ curabsdata, ... 0299 curabsdata, ... 0300 'shaftwidth', 2 * get(haxs, 'LineWidth'), ... 0301 'headwidth', 0.25 * get(haxs, 'FontSize'), ... 0302 'headlength', 0.25 * get(haxs, 'FontSize'), ... 0303 'clip', 'on'); 0304 end 0305 % Plot planned waypoint path. 0306 hwpt = m_plot(options.wptlondata, options.wptlatdata, ... 0307 'LineStyle', ':', 'LineWidth', 1.5 * get(haxs, 'LineWidth'), ... 0308 'Marker', 'x', 'MarkerSize', 0.5 * get(haxs, 'FontSize'), ... 0309 'Color', 'black'); 0310 % Plot glider trajectory. 0311 htrj = m_plot(options.londata, options.latdata, ... 0312 'LineStyle', '-', 'LineWidth', 1.5 * get(haxs, 'LineWidth'), ... 0313 'Marker', 'none', ... 0314 'Color', 'black'); 0315 % Plot initial and final trajectory points. 0316 trj_frst = ... 0317 find(~(isnan(options.londata(:)) | isnan(options.latdata(:))), 1, 'first'); 0318 trj_last = ... 0319 find(~(isnan(options.londata(:)) | isnan(options.latdata(:))), 1, 'last'); 0320 hbeg = m_plot(options.londata(trj_frst), options.latdata(trj_frst), ... 0321 'LineStyle', 'none', ... 0322 'Marker', 'o', 'MarkerSize', 1/3 * get(haxs, 'FontSize'), ... 0323 'MarkerEdgeColor', 'black', 'MarkerFaceColor', 'black'); 0324 hend = m_plot(options.londata(trj_last), options.latdata(trj_last), ... 0325 'LineStyle', 'none', ... 0326 'Marker', 'o', 'MarkerSize', 1/3 * get(haxs, 'FontSize'), ... 0327 'MarkerEdgeColor', 'black', 'MarkerFaceColor', 'white'); 0328 0329 0330 %% Add legends for glider trajectory and planned waypoint path. 0331 set(htrj, 'DisplayName', 'glider trajectory'); 0332 set(hbeg, 'DisplayName', 'first position'); 0333 set(hend, 'DisplayName', 'last position'); 0334 set(hwpt, 'DisplayName', 'planned waypoint path'); 0335 if any(ishghandle([htrj hbeg hend hwpt])) 0336 hlgn = legend([htrj hbeg hend hwpt]); 0337 end 0338 0339 0340 %% Restore figure and axes properties, if needed. 0341 if ~haxs_hold 0342 hold(haxs, 'off'); 0343 end 0344 0345 end