PLOTTRANSECTVERTICALSECTION Plot vertical section of scatter data from a glider transect. Syntax: PLOTTRANSECTVERTICALSECTION(OPTIONS) PLOTTRANSECTVERTICALSECTION(OPT1, VAL1, ...) PLOTTRANSECTVERTICALSECTION(H, OPTIONS) PLOTTRANSECTVERTICALSECTION(H, OPT1, VAL1, ...) [HFIG, HAXS, HCBA, HSCT] = PLOTTRANSECTVERTICALSECTION(...) Description: PLOTTRANSECTVERTICALSECTION(OPTIONS) and PLOTTRANSECTVERTICALSECTION(OPT1, VAL1, ...) generate a new figure with a scatter plot of scalar data collected during a glider transect according to options in string key-value pairs OPT1, VAL1... or in struct OPTIONS with field names as option keys and field values as option values. The scatter plot is generated with the function SCATTER. See note on performance and invalid values. Recognized options are: XDATA: horizontal coordinate data. Vector of data to be passed as x coordindate to function SCATTER, usually distance or time. Default value: [] YDATA: vertical coordinate data. Vector of data to be passed as y coordindate to function SCATTER, usually pressure or depth. Default value: [] CDATA: measured variable data. Vector of data to be passed as color coordindate to function SCATTER. Default value: [] SDATA: data marker size. Vector or scalar to be passed as size coordindate to function SCATTER. Default value: [] 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() LOGSCALE: use logarithmic color scale instead of linear scale. Boolean specifying whether color scale should be logarithmic instead of linear. See note on logarithmic color scaling. Default value: false DATETICKS: use date formatted tick labels for selected axes. Substring of 'xyz' specifying which axes should be labeled with date formatted ticks using function DATETICKS. Default value: '' 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() PLOTTRANSECTVERTICALSECTION(H, ...) does not create a new figure, but plots to figure given by figure handle H. [HFIG, HAXS, HCBA, HSCT] = PLOTTRANSECTVERTICALSECTION(...) returns handles for the figure, axes, color bar, and scatter group in HFIG, HAXS, HSCT, and HCBA, respectively. Notes: Invalid values (NaN) introduce a signficant performance penalty in the plotting functions. They are discarded without modifying the final appearance of the plot. There is no built-in support for logarithmic color scaling. The effect is emulated hacking the color data and the color bar ticks. Examples: [hfig, haxs, hcba, hsct] = ... plotTransectVerticalSection(gcf, ... 'xdata', now+30*rand(100,1), 'xlabel', struct('String', 'x'), ... 'ydata', rand(100,1), 'ylabel', struct('String', 'y'), ... 'cdata', 10.^(3*rand(100,1)), 'clabel', struct('String', 'c'), ... 'sdata', 25, 'logscale', true, 'dateticks', 'x', ... 'title', struct('String', 'Random scatter plot'), ... 'axsprops', struct('XGrid', 'on', 'YGrid', 'on', 'PlotBoxAspectRatio', [2 1 1]), ... 'figprops', struct('Name', 'Vertical section example') ) See also: SCATTER COLORBAR DATETICK SET Authors: Joan Pau Beltran <joanpau.beltran@socib.cat>
0001 function [hfig, haxs, hcba, hsct] = plotTransectVerticalSection(varargin) 0002 %PLOTTRANSECTVERTICALSECTION Plot vertical section of scatter data from a glider transect. 0003 % 0004 % Syntax: 0005 % PLOTTRANSECTVERTICALSECTION(OPTIONS) 0006 % PLOTTRANSECTVERTICALSECTION(OPT1, VAL1, ...) 0007 % PLOTTRANSECTVERTICALSECTION(H, OPTIONS) 0008 % PLOTTRANSECTVERTICALSECTION(H, OPT1, VAL1, ...) 0009 % [HFIG, HAXS, HCBA, HSCT] = PLOTTRANSECTVERTICALSECTION(...) 0010 % 0011 % Description: 0012 % PLOTTRANSECTVERTICALSECTION(OPTIONS) and 0013 % PLOTTRANSECTVERTICALSECTION(OPT1, VAL1, ...) generate a new figure with a 0014 % scatter plot of scalar data collected during a glider transect according to 0015 % options in string key-value pairs OPT1, VAL1... or in struct OPTIONS with 0016 % field names as option keys and field values as option values. 0017 % The scatter plot is generated with the function SCATTER. 0018 % See note on performance and invalid values. 0019 % Recognized options are: 0020 % XDATA: horizontal coordinate data. 0021 % Vector of data to be passed as x coordindate to function SCATTER, 0022 % usually distance or time. 0023 % Default value: [] 0024 % YDATA: vertical coordinate data. 0025 % Vector of data to be passed as y coordindate to function SCATTER, 0026 % usually pressure or depth. 0027 % Default value: [] 0028 % CDATA: measured variable data. 0029 % Vector of data to be passed as color coordindate to function SCATTER. 0030 % Default value: [] 0031 % SDATA: data marker size. 0032 % Vector or scalar to be passed as size coordindate to function SCATTER. 0033 % Default value: [] 0034 % XLABEL: horizontal axis label data. 0035 % Struct defining x label properties. 0036 % The text of the label is in property 'String'. 0037 % Default value: struct() 0038 % YLABEL: vertical axis label data. 0039 % Struct defining y label properties. 0040 % The text of the label is in property 'String'. 0041 % Default value: struct() 0042 % CLABEL: color bar label data. 0043 % Struct defining color bar label properties. 0044 % The text of the label is in property 'String'. 0045 % Actually this will be the colorbar's child object 'Title'. 0046 % Default value: struct() 0047 % TITLE: axes title data. 0048 % Struct defining axes title properties. 0049 % The text of the label is in property 'String'. 0050 % Default value: struct() 0051 % LOGSCALE: use logarithmic color scale instead of linear scale. 0052 % Boolean specifying whether color scale should be logarithmic instead of 0053 % linear. See note on logarithmic color scaling. 0054 % Default value: false 0055 % DATETICKS: use date formatted tick labels for selected axes. 0056 % Substring of 'xyz' specifying which axes should be labeled with date 0057 % formatted ticks using function DATETICKS. 0058 % Default value: '' 0059 % AXSPROPS: extra axis properties. 0060 % Struct of axis properties to set for the plot axes with function SET. 0061 % Default value: struct() 0062 % FIGPROPS: extra figure properties. 0063 % Struct of figure properties to set for the figure with function SET. 0064 % Default value: struct() 0065 % 0066 % PLOTTRANSECTVERTICALSECTION(H, ...) does not create a new figure, 0067 % but plots to figure given by figure handle H. 0068 % 0069 % [HFIG, HAXS, HCBA, HSCT] = PLOTTRANSECTVERTICALSECTION(...) returns 0070 % handles for the figure, axes, color bar, and scatter group in 0071 % HFIG, HAXS, HSCT, and HCBA, respectively. 0072 % 0073 % Notes: 0074 % Invalid values (NaN) introduce a signficant performance penalty in the 0075 % plotting functions. They are discarded without modifying the final 0076 % appearance of the plot. 0077 % 0078 % There is no built-in support for logarithmic color scaling. 0079 % The effect is emulated hacking the color data and the color bar ticks. 0080 % 0081 % Examples: 0082 % [hfig, haxs, hcba, hsct] = ... 0083 % plotTransectVerticalSection(gcf, ... 0084 % 'xdata', now+30*rand(100,1), 'xlabel', struct('String', 'x'), ... 0085 % 'ydata', rand(100,1), 'ylabel', struct('String', 'y'), ... 0086 % 'cdata', 10.^(3*rand(100,1)), 'clabel', struct('String', 'c'), ... 0087 % 'sdata', 25, 'logscale', true, 'dateticks', 'x', ... 0088 % 'title', struct('String', 'Random scatter plot'), ... 0089 % 'axsprops', struct('XGrid', 'on', 'YGrid', 'on', 'PlotBoxAspectRatio', [2 1 1]), ... 0090 % 'figprops', struct('Name', 'Vertical section example') ) 0091 % 0092 % See also: 0093 % SCATTER 0094 % COLORBAR 0095 % DATETICK 0096 % SET 0097 % 0098 % Authors: 0099 % Joan Pau Beltran <joanpau.beltran@socib.cat> 0100 0101 % Copyright (C) 2013-2016 0102 % ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears 0103 % <http://www.socib.es> 0104 % 0105 % This program is free software: you can redistribute it and/or modify 0106 % it under the terms of the GNU General Public License as published by 0107 % the Free Software Foundation, either version 3 of the License, or 0108 % (at your option) any later version. 0109 % 0110 % This program is distributed in the hope that it will be useful, 0111 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0112 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0113 % GNU General Public License for more details. 0114 % 0115 % You should have received a copy of the GNU General Public License 0116 % along with this program. If not, see <http://www.gnu.org/licenses/>. 0117 0118 % No argument number checking since any number of arguments is allowed. 0119 0120 %% Set plot options and default values. 0121 options = struct(); 0122 options.xdata = []; 0123 options.ydata = []; 0124 options.cdata = []; 0125 options.sdata = []; 0126 options.xlabel = struct(); 0127 options.ylabel = struct(); 0128 options.clabel = struct(); 0129 options.title = struct(); 0130 options.logscale = false; 0131 options.dateticks = ''; 0132 options.axsprops = struct(); 0133 options.figprops = struct(); 0134 0135 0136 %% Get optional figure handle and option arguments. 0137 if (nargin > 0) && isscalar(varargin{1}) && ishghandle(varargin{1}) 0138 args = varargin(2:end); 0139 hfig = figure(varargin{1}); 0140 else 0141 args = varargin; 0142 hfig = figure(); 0143 end 0144 0145 0146 %% Get options from extra arguments. 0147 % Parse option key-value pairs in any accepted call signature. 0148 if isscalar(args) && isstruct(args{1}) 0149 % Options passed as a single option struct argument: 0150 % field names are option keys and field values are option values. 0151 option_key_list = fieldnames(args{1}); 0152 option_val_list = struct2cell(args{1}); 0153 elseif mod(numel(args), 2) == 0 0154 % Options passed as key-value argument pairs. 0155 option_key_list = args(1:2:end); 0156 option_val_list = args(2:2:end); 0157 else 0158 error('glider_toolbox:plotTransectVerticalSection:InvalidOptions', ... 0159 'Invalid optional arguments (neither key-value pairs nor struct).'); 0160 end 0161 % Overwrite default options with values given in extra arguments. 0162 for opt_idx = 1:numel(option_key_list) 0163 opt = lower(option_key_list{opt_idx}); 0164 val = option_val_list{opt_idx}; 0165 if isfield(options, opt) 0166 options.(opt) = val; 0167 else 0168 error('glider_toolbox:plotTransectVerticalSection:InvalidOption', ... 0169 'Invalid option: %s.', opt); 0170 end 0171 end 0172 0173 0174 %% Set figure properties. 0175 set(hfig, options.figprops); 0176 0177 0178 %% Initialize all plot elements. 0179 haxs = gca(); 0180 hsct = scatter(haxs, [], [], [], [], 'fill'); 0181 hcba = colorbar('SouthOutside'); 0182 haxstit = title(haxs, []); 0183 haxsxlb = xlabel(haxs, []); 0184 haxsylb = ylabel(haxs, []); 0185 hcbatit = get(hcba, 'XLabel'); 0186 0187 0188 %% Compute mask to discard invalid values to speedup plotting. 0189 % Size data might be empty to use default marker size in SCATTER. 0190 valid = ~(isnan(options.xdata) | isnan(options.ydata) | isnan(options.cdata)); 0191 if (~isempty(options.sdata)) 0192 valid = valid & ~isnan(options.sdata); 0193 end 0194 0195 0196 %% Set properties of plot elements. 0197 % Use an equivalent way to compute quantile without using QUANTILE function 0198 % in statistical toolbox. See documentation there for algorithm details. 0199 % crange = quantile(options.cdata(valid), crange_quantiles); 0200 crange_quantiles = [0.01 0.99]; 0201 cdata_sorted = sort(options.cdata(valid)); 0202 if isempty(cdata_sorted) 0203 crange = [0.5 1.5]; % some arbitrary value to let the rest of code work. 0204 else 0205 crange = interp1(cdata_sorted([1 1:end end]),... 0206 crange_quantiles * numel(cdata_sorted) + 1.5); 0207 end 0208 xrange = [min(options.xdata(:)) max(options.xdata(:))]; 0209 yrange = [min(options.ydata(:)) max(options.ydata(:))]; 0210 if options.logscale 0211 % Hack to plot a color bar with logarithmic scale and linear ticks. 0212 % This code should go after colormap call, otherwise colormap resets ticks. 0213 if isscalar(options.sdata) 0214 set(hsct, ... 0215 'XData', options.xdata(valid), ... 0216 'YData', options.ydata(valid), ... 0217 'CData', log10(options.cdata(valid)), ... 0218 'SizeData', options.sdata); 0219 elseif ~isempty(options.sdata) 0220 set(hsct, ... 0221 'XData', options.xdata(valid), ... 0222 'YData', options.ydata(valid), ... 0223 'CData', log10(options.cdata(valid)), ... 0224 'SizeData', options.sdata(valid)); 0225 end 0226 % Force range to prevent error due to wrong non-positive values. 0227 % These values should not be there for logarithmic scale magnitudes 0228 % (e.g. chlorophyll concentration). 0229 if crange(2) <= 0 0230 crange = log10(realmin('double')*[1 10]); 0231 elseif crange(1) <= 0 0232 crange = log10(sort([min(options.cdata(options.cdata(:)>0)) crange(2)])); 0233 else 0234 crange = log10(crange); 0235 end 0236 if diff(crange) == 0 0237 crange = crange + 0.5 * [-1 1]; 0238 end 0239 ctick = bsxfun(@plus, log10(1:9)', floor(crange(1)) : floor(crange(2))); 0240 ctick = ctick(crange(1) <= ctick & ctick <= crange(2)); 0241 ctick_label = cell(size(ctick)); 0242 switch floor(diff(crange)) 0243 case 0 0244 ctick_show = true(size(ctick)); 0245 case 1 0246 ctick_show = [true ; rem(ctick(2:end-1), 1) == 0 ; true]; 0247 otherwise 0248 ctick_show = (rem(ctick, 1) == 0); 0249 end 0250 ctick_label(ctick_show) = strtrim(cellstr(num2str(10.^ctick(ctick_show)))); 0251 drawnow(); % Hack to force plot update before setting color axis properties. 0252 set(haxs, 'CLim', crange, 'XLim', xrange, 'YLim', yrange); 0253 set(hcba, 'XTick', ctick, 'XTickLabel', ctick_label); 0254 else 0255 if isscalar(options.sdata) 0256 set(hsct, ... 0257 'XData', options.xdata(valid), ... 0258 'YData', options.ydata(valid), ... 0259 'CData', options.cdata(valid), ... 0260 'SizeData', options.sdata); 0261 elseif ~isempty(options.sdata) 0262 set(hsct, ... 0263 'XData', options.xdata(valid), ... 0264 'YData', options.ydata(valid), ... 0265 'CData', options.cdata(valid), ... 0266 'SizeData', options.sdata(valid)); 0267 end 0268 % Prevent range error when color range contains one single value. 0269 if diff(crange) == 0 0270 crange = crange + 0.5 * [-1 1]; 0271 end 0272 set(haxs, 'CLim', crange, 'XLim', xrange, 'YLim', yrange); 0273 end 0274 for a = 'xyz' 0275 if ismember(a, options.dateticks) 0276 arange = diff(get(haxs, [a 'lim'])); 0277 if arange > 365 0278 datetick_format = 'yyyy mmm'; 0279 elseif arange > 2 0280 datetick_format = 'mmm dd'; 0281 else 0282 datetick_format = 'HH:mm:ss'; 0283 end 0284 datetick(a, datetick_format, 'keeplimits'); 0285 end 0286 end 0287 set(haxs, options.axsprops); 0288 set(haxstit, options.title); 0289 set(haxsxlb, options.xlabel); 0290 set(haxsylb, options.ylabel); 0291 set(hcbatit, options.clabel); 0292 0293 end