time | Calls | line |
|---|
| | 1 | function theAxis = subplot(varargin)
|
| | 2 | %SUBPLOT Create axes in tiled positions.
|
| | 3 | % H = SUBPLOT(m,n,p), or SUBPLOT(mnp), breaks the Figure window
|
| | 4 | % into an m-by-n matrix of small axes, selects the p-th axes for
|
| | 5 | % the current plot, and returns the axes handle. The axes are
|
| | 6 | % counted along the top row of the Figure window, then the second
|
| | 7 | % row, etc. For example,
|
| | 8 | %
|
| | 9 | % SUBPLOT(2,1,1), PLOT(income)
|
| | 10 | % SUBPLOT(2,1,2), PLOT(outgo)
|
| | 11 | %
|
| | 12 | % plots income on the top half of the window and outgo on the
|
| | 13 | % bottom half. If the CurrentAxes is nested in a uipanel the
|
| | 14 | % panel is used as the parent for the subplot instead of the
|
| | 15 | % current figure.
|
| | 16 | %
|
| | 17 | % SUBPLOT(m,n,p), if the axes already exists, makes it current.
|
| | 18 | % SUBPLOT(m,n,p,'replace'), if the axes already exists, deletes it and
|
| | 19 | % creates a new axes.
|
| | 20 | % SUBPLOT(m,n,p,'align') places the axes so that the plot boxes
|
| | 21 | % are aligned, but does not prevent the labels and ticks from
|
| | 22 | % overlapping.
|
| | 23 | % SUBPLOT(m,n,P), where P is a vector, specifies an axes position
|
| | 24 | % that covers all the subplot positions listed in P.
|
| | 25 | % SUBPLOT(H), where H is an axes handle, is another way of making
|
| | 26 | % an axes current for subsequent plotting commands.
|
| | 27 | %
|
| | 28 | % SUBPLOT('position',[left bottom width height]) creates an
|
| | 29 | % axes at the specified position in normalized coordinates (in
|
| | 30 | % in the range from 0.0 to 1.0).
|
| | 31 | %
|
| | 32 | % SUBPLOT(..., PROP1, VALUE1, PROP2, VALUE2, ...) sets the
|
| | 33 | % specified property-value pairs on the subplot axes. To add the
|
| | 34 | % subplot to a specific figure pass the figure handle as the
|
| | 35 | % value for the 'Parent' property.
|
| | 36 | %
|
| | 37 | % If a SUBPLOT specification causes a new axes to overlap an
|
| | 38 | % existing axes, the existing axes is deleted - unless the position
|
| | 39 | % of the new and existing axes are identical. For example,
|
| | 40 | % the statement SUBPLOT(1,2,1) deletes all existing axes overlapping
|
| | 41 | % the left side of the Figure window and creates a new axes on that
|
| | 42 | % side - unless there is an axes there with a position that exactly
|
| | 43 | % matches the position of the new axes (and 'replace' was not specified),
|
| | 44 | % in which case all other overlapping axes will be deleted and the
|
| | 45 | % matching axes will become the current axes.
|
| | 46 | %
|
| | 47 | % SUBPLOT(111) is an exception to the rules above, and is not
|
| | 48 | % identical in behavior to SUBPLOT(1,1,1). For reasons of backwards
|
| | 49 | % compatibility, it is a special case of subplot which does not
|
| | 50 | % immediately create an axes, but instead sets up the figure so that
|
| | 51 | % the next graphics command executes CLF RESET in the figure
|
| | 52 | % (deleting all children of the figure), and creates a new axes in
|
| | 53 | % the default position. This syntax does not return a handle, so it
|
| | 54 | % is an error to specify a return argument. The delayed CLF RESET
|
| | 55 | % is accomplished by setting the figure's NextPlot to 'replace'.
|
| | 56 | %
|
| | 57 | % Be aware when creating subplots from scripts that the Position
|
| | 58 | % property of subplots is not finalized until either a drawnow
|
| | 59 | % command is issued, or MATLAB returns to await a user command.
|
| | 60 | % That is, the value obtained for subplot i by the command
|
| | 61 | % h(i).Position will not be correct until the script
|
| | 62 | % refreshes the plot or exits.
|
| | 63 | %
|
| | 64 | % See also GCA, GCF, AXES, FIGURE, UIPANEL
|
| | 65 |
|
| | 66 | % SUBPLOT(m,n,p,H) when H is an axes will move H to the specified
|
| | 67 | % position.
|
| | 68 | % SUBPLOT(m,n,p,H,PROP1,VALUE1,...) will move H and apply the
|
| | 69 | % specified property-value pairs
|
| | 70 | %
|
| | 71 | % SUBPLOT(m,n,p) for non-integer p places the subplot at the
|
| | 72 | % fraction p-floor(p) between the positions floor(p) and ceil(p)
|
| | 73 |
|
| | 74 | % Copyright 1984-2020 The MathWorks, Inc.
|
| | 75 |
|
| | 76 | % Separate out name/value pairs and string arguments from other arguments.
|
| | 77 | % This will also convert a '222' first input into [2,2,2].
|
0.022 | 4 | 78 | [args,pvpairs,narg] = subplot_parseargs(varargin);
|
| | 79 |
|
| | 80 | % Check whether we should ignore a possible 'v6' argument.
|
< 0.001 | 4 | 81 | if ~isempty(pvpairs) && strcmpi(pvpairs{1}, 'v6')
|
| | 82 | filename = 'subplot';
|
| | 83 | warning(['MATLAB:', filename, ':IgnoringV6Argument'],...
|
| | 84 | getString(message('MATLAB:usev6plotapi:IgnoringV6ArgumentForFilename', upper(filename))));
|
| | 85 | pvpairs(1) = [];
|
< 0.001 | 4 | 86 | end
|
| | 87 |
|
| | 88 |
|
| | 89 | % we will kill all overlapping axes siblings if we encounter the mnp
|
| | 90 | % or m,n,p specifier (excluding '111').
|
| | 91 | % But if we get the 'position' or H specifier, we won't check for and
|
| | 92 | % delete overlapping siblings:
|
< 0.001 | 4 | 93 | killSiblings = 0;
|
< 0.001 | 4 | 94 | createAxis = true;
|
< 0.001 | 4 | 95 | moveAxis = false;
|
< 0.001 | 4 | 96 | delayDestroy = false;
|
< 0.001 | 4 | 97 | useAutoLayout = true;
|
< 0.001 | 4 | 98 | tol = sqrt(eps);
|
< 0.001 | 4 | 99 | parent = handle(get(0, 'CurrentFigure'));
|
< 0.001 | 4 | 100 | ancestorFigure = parent;
|
< 0.001 | 4 | 101 | if ~isempty(parent) && ~isempty(parent.CurrentAxes)
|
< 0.001 | 3 | 102 | parent = parent.CurrentAxes.Parent;
|
< 0.001 | 3 | 103 | ancestorFigure = parent;
|
< 0.001 | 3 | 104 | if ~strcmp(ancestorFigure.Type, 'figure')
|
| | 105 | ancestorFigure = ancestor(parent, 'figure');
|
< 0.001 | 3 | 106 | end
|
< 0.001 | 4 | 107 | end
|
< 0.001 | 4 | 108 | preventMove = false;
|
| | 109 |
|
| | 110 | % This is the percent offset from the subplot grid of the plotbox.
|
< 0.001 | 4 | 111 | inset = [.2, .18, .04, .1]; % [left bottom right top]
|
| | 112 |
|
| | 113 | %check for encoded format
|
< 0.001 | 4 | 114 | h = [];
|
< 0.001 | 4 | 115 | position = [];
|
< 0.001 | 4 | 116 | explicitParent = false;
|
< 0.001 | 4 | 117 | explicitPosition = false;
|
< 0.001 | 4 | 118 | nRows = [];
|
| | 119 |
|
< 0.001 | 4 | 120 | if narg == 0
|
| | 121 | % The argument could be either:
|
| | 122 | % 1) subplot()
|
| | 123 | % 2) subplot('Position',positionVector)
|
| | 124 | if isempty(pvpairs)
|
| | 125 | % subplot()
|
| | 126 | % make compatible with 3.5, i.e. subplot == subplot(111)
|
| | 127 | args{1} = 111;
|
| | 128 | narg = 1;
|
| | 129 | elseif strcmpi(pvpairs{1}, 'position')
|
| | 130 | % subplot('Position',positionVector)
|
| | 131 | if numel(pvpairs)>=2
|
| | 132 | pos_size = size(pvpairs{2});
|
| | 133 | if (pos_size(1) * pos_size(2) == 4)
|
| | 134 | position = pvpairs{2};
|
| | 135 | explicitPosition = true;
|
| | 136 | else
|
| | 137 | error(message('MATLAB:subplot:InvalidPositionParameter'))
|
| | 138 | end
|
| | 139 | else
|
| | 140 | error(message('MATLAB:subplot:InvalidPositionParameter'))
|
| | 141 | end
|
| | 142 | killSiblings = 1; % Kill overlaps here also.
|
| | 143 | useAutoLayout = false;
|
| | 144 | pvpairs(1:2) = [];
|
| | 145 | else
|
| | 146 | error(message('MATLAB:subplot:UnknownOption'))
|
| | 147 | end
|
< 0.001 | 4 | 148 | end
|
| | 149 |
|
< 0.001 | 4 | 150 | if narg == 1
|
| | 151 | % The argument could be one of 2 things:
|
| | 152 | % 1) a 3-digit number 100 < num < 1000, of the format mnp
|
| | 153 | % 2) an axes handle
|
| | 154 | arg = args{1};
|
| | 155 |
|
| | 156 | % Check whether arg is a handle to an Axes/Chart.
|
| | 157 | if isempty(arg)
|
| | 158 | error(message('MATLAB:subplot:UnknownOption'))
|
| | 159 | elseif isSubplotCandidate(arg)
|
| | 160 | h = handle(arg);
|
| | 161 | if isa(h, 'matlab.graphics.chart.Chart') ...
|
| | 162 | && ~isprop(h,'InnerPosition') ...
|
| | 163 | && ~isappdata(h,'SubplotPosition')
|
| | 164 | error(message('MATLAB:subplot:UnsupportedSyntaxWithChart',h.Type));
|
| | 165 | end
|
| | 166 |
|
| | 167 | createAxis = false;
|
| | 168 | elseif isnumeric(arg)
|
| | 169 | % Check for NaN and Inf.
|
| | 170 | if (~isfinite(arg))
|
| | 171 | error(message('MATLAB:subplot:SubplotIndexNonFinite'))
|
| | 172 | end
|
| | 173 |
|
| | 174 | % Check for input out of range
|
| | 175 | if (arg <= 100 || arg >= 1000)
|
| | 176 | error(message('MATLAB:subplot:SubplotIndexOutOfRange'))
|
| | 177 | end
|
| | 178 |
|
| | 179 | plotId = rem(arg, 10);
|
| | 180 | nCols = rem(fix(arg - plotId) / 10, 10);
|
| | 181 | nRows = fix(arg / 100);
|
| | 182 | if nRows * nCols < plotId
|
| | 183 | error(message('MATLAB:subplot:SubplotIndexTooLarge'));
|
| | 184 | end
|
| | 185 | killSiblings = 1;
|
| | 186 | if (arg == 111)
|
| | 187 | createAxis = false;
|
| | 188 | delayDestroy = true;
|
| | 189 | if nargout > 0
|
| | 190 | error(message('MATLAB:subplot:TooManyOutputs'))
|
| | 191 | end
|
| | 192 | else
|
| | 193 | createAxis = true;
|
| | 194 | delayDestroy = false;
|
| | 195 | end
|
| | 196 | else
|
| | 197 | error(message('MATLAB:subplot:InvalidAxesHandle'))
|
| | 198 | end
|
| | 199 |
|
< 0.001 | 4 | 200 | elseif narg == 2
|
| | 201 | % passed in subplot(a,b) where a/b are not a name/value pair
|
| | 202 | error(message('MATLAB:subplot:InvalidSyntax'))
|
| | 203 |
|
< 0.001 | 4 | 204 | elseif narg == 3
|
| | 205 | % passed in subplot(m,n,p)
|
< 0.001 | 4 | 206 | nRows = args{1};
|
< 0.001 | 4 | 207 | nCols = args{2};
|
< 0.001 | 4 | 208 | plotId = args{3};
|
| | 209 |
|
| | 210 | % we should kill overlaps here too:
|
< 0.001 | 4 | 211 | killSiblings = 1;
|
| | 212 |
|
| | 213 | elseif narg == 4
|
| | 214 | % passed in subplot(m,n,p,ax)
|
| | 215 |
|
| | 216 | nRows = args{1};
|
| | 217 | nCols = args{2};
|
| | 218 | plotId = args{3};
|
| | 219 |
|
| | 220 | arg = args{4};
|
| | 221 | if isempty(arg)
|
| | 222 | error(message('MATLAB:subplot:InvalidAxesHandle'))
|
| | 223 | else
|
| | 224 | h = handle(arg);
|
| | 225 | if isa(h, 'matlab.graphics.chart.Chart') ...
|
| | 226 | && ~isObjectAlreadyInCell(args{1},args{2},args{3},h)...
|
| | 227 | && ~(isa(h,'matlab.graphics.chart.internal.SubplotPositionableChart')...
|
| | 228 | || isa(h,'matlab.graphics.chart.internal.PositionableChartWithAxes'))
|
| | 229 | error(message('MATLAB:subplot:UnsupportedSyntaxWithChart',h.Type));
|
| | 230 | elseif ~isSubplotCandidate(h)
|
| | 231 | error(message('MATLAB:subplot:InvalidAxesHandle'))
|
| | 232 | end
|
| | 233 |
|
| | 234 | parent = h.Parent;
|
| | 235 | ancestorFigure = ancestor(h, 'figure');
|
| | 236 |
|
| | 237 | % If the parent is passed in explicitly, don't create a new figure
|
| | 238 | % when the "NextPlot" property is set to "new" in the figure.
|
| | 239 | explicitParent = true;
|
| | 240 | ancestorFigure.CurrentAxes = h;
|
| | 241 | moveAxis = true;
|
| | 242 | createAxis = false;
|
| | 243 |
|
| | 244 | if ~isempty(pvpairs) && strcmpi(pvpairs{1}, 'PreventMove')
|
| | 245 | preventMove = true;
|
| | 246 | pvpairs{1} = [];
|
| | 247 | end
|
| | 248 | end
|
| | 249 |
|
| | 250 | elseif narg > 4
|
| | 251 | % String inputs have already been removed
|
| | 252 | % so any other number of non-string inputs is invalid syntax.
|
| | 253 | error(message('MATLAB:subplot:UnknownOption'))
|
| | 254 |
|
< 0.001 | 4 | 255 | end
|
| | 256 |
|
| | 257 | % Check for 'replace' or 'align' in the properties.
|
< 0.001 | 4 | 258 | if ~isempty(pvpairs)
|
| | 259 | arg = pvpairs{1};
|
| | 260 | if strncmpi(arg, 'replace', 1)
|
| | 261 | % passed in subplot(m,n,p,'replace')
|
| | 262 | killSiblings = 2; % kill nomatter what
|
| | 263 | pvpairs(1) = [];
|
| | 264 | elseif strcmpi(arg, 'align')
|
| | 265 | % passed in subplot(m,n,p,'align')
|
| | 266 | % since obeying position will remove the axes from the grid just set
|
| | 267 | % useAutoLayout to false to skip adding it to the grid to start with
|
| | 268 | useAutoLayout = false;
|
| | 269 | killSiblings = 1; % kill if it overlaps stuff
|
| | 270 | pvpairs(1) = [];
|
| | 271 | end
|
< 0.001 | 4 | 272 | end
|
| | 273 |
|
| | 274 | % Find and remove any 'Parent' property passed in as a name/value pair.
|
< 0.001 | 4 | 275 | par = 2*find(strncmpi('Parent', pvpairs(1 : 2 : end), 6));
|
< 0.001 | 4 | 276 | if any(par)
|
| | 277 | % If the parent is passed in explicitly, don't create a new figure
|
| | 278 | % when the "NextPlot" property is set to "new" in the figure.
|
| | 279 | explicitParent = true;
|
| | 280 | parent = handle(pvpairs{par(end)});
|
| | 281 | ancestorFigure = ancestor(parent, 'figure');
|
| | 282 | pvpairs([par-1 par]) = [];
|
< 0.001 | 4 | 283 | end
|
| | 284 |
|
| | 285 | % Warn for n-v pairs that shouldn't be set on Axes in a subplot.
|
| | 286 | % Also warns on substrings of these properties
|
< 0.001 | 4 | 287 | unsupportedArgs = {'Position','OuterPosition','InnerPosition','ActivePositionProperty','PositionConstraint'};
|
< 0.001 | 4 | 288 | for prop = pvpairs(1 : 2 : end)
|
| | 289 | argmatches = strncmpi(unsupportedArgs, prop{:}, length(prop{:}));
|
| | 290 | if(argmatches(1))
|
| | 291 | warning(message('MATLAB:subplot:InvalidPositionSyntax'));
|
| | 292 | elseif any(argmatches(2:end))
|
| | 293 | warning(message('MATLAB:subplot:InvalidNVPair', ...
|
| | 294 | unsupportedArgs{find(argmatches,1)}));
|
| | 295 | end
|
| | 296 | end
|
| | 297 |
|
| | 298 | % if we recovered an identifier earlier, use it:
|
< 0.001 | 4 | 299 | if ~isempty(h) && ~moveAxis
|
| | 300 | % Syntax: subplot(ax)
|
| | 301 | parent = h.Parent;
|
| | 302 | ancestorFigure = ancestor(h, 'figure');
|
| | 303 | ancestorFigure.CurrentAxes = h;
|
< 0.001 | 4 | 304 | else % if we haven't recovered position yet, generate it from mnp info:
|
< 0.001 | 4 | 305 | if isempty(parent)
|
0.299 | 1 | 306 | parent = gcf;
|
< 0.001 | 1 | 307 | ancestorFigure = parent;
|
< 0.001 | 4 | 308 | end
|
| | 309 |
|
| | 310 | % Error if AutoResizeChildren is 'on'
|
< 0.001 | 4 | 311 | if isprop(parent,'AutoResizeChildren') && strcmp(parent.AutoResizeChildren,'on')
|
| | 312 | error(message('MATLAB:subplot:AutoResizeChildren'))
|
< 0.001 | 4 | 313 | end
|
| | 314 |
|
< 0.001 | 4 | 315 | if isempty(position)
|
< 0.001 | 4 | 316 | if min(plotId) < 1
|
| | 317 | error(message('MATLAB:subplot:SubplotIndexTooSmall'))
|
< 0.001 | 4 | 318 | elseif max(plotId) > nCols * nRows
|
| | 319 | error(message('MATLAB:subplot:SubplotIndexTooLarge'));
|
< 0.001 | 4 | 320 | else
|
| | 321 |
|
< 0.001 | 4 | 322 | row = (nRows - 1) - fix((plotId - 1) / nCols);
|
< 0.001 | 4 | 323 | col = rem(plotId - 1, nCols);
|
| | 324 |
|
| | 325 | % get default axes position in normalized units
|
| | 326 | % If we have checked this quantity once, cache it.
|
< 0.001 | 4 | 327 | if ~isappdata(ancestorFigure, 'SubplotDefaultAxesLocation')
|
< 0.001 | 1 | 328 | if ~strcmp(get(ancestorFigure, 'DefaultAxesUnits'), 'normalized')
|
| | 329 | tmp = axes('Parent',ancestorFigure);
|
| | 330 | tmp.Units = 'normalized';
|
| | 331 | def_pos = tmp.InnerPosition;
|
| | 332 | delete(tmp)
|
< 0.001 | 1 | 333 | else
|
< 0.001 | 1 | 334 | def_pos = get(ancestorFigure, 'DefaultAxesPosition');
|
< 0.001 | 1 | 335 | end
|
< 0.001 | 1 | 336 | setappdata(ancestorFigure, 'SubplotDefaultAxesLocation', def_pos);
|
< 0.001 | 1 | 337 | if(parent ~= ancestorFigure)
|
| | 338 | setappdata(parent, 'SubplotDefaultAxesLocation', def_pos);
|
< 0.001 | 1 | 339 | end
|
< 0.001 | 3 | 340 | else
|
< 0.001 | 3 | 341 | def_pos = getappdata(ancestorFigure, 'SubplotDefaultAxesLocation');
|
< 0.001 | 4 | 342 | end
|
| | 343 |
|
| | 344 | % compute outerposition and insets relative to figure bounds
|
< 0.001 | 4 | 345 | rw = max(row) - min(row) + 1;
|
< 0.001 | 4 | 346 | cw = max(col) - min(col) + 1;
|
< 0.001 | 4 | 347 | width = def_pos(3) / (nCols - inset(1) - inset(3));
|
< 0.001 | 4 | 348 | height = def_pos(4) / (nRows - inset(2) - inset(4));
|
< 0.001 | 4 | 349 | inset = inset .* [width, height, width, height];
|
< 0.001 | 4 | 350 | outerpos = [def_pos(1) + min(col) * width - inset(1), ...
|
| 4 | 351 | def_pos(2) + min(row) * height - inset(2), ...
|
| 4 | 352 | width * cw, height * rw];
|
| | 353 |
|
| | 354 | % adjust outerpos and insets for axes around the outside edges
|
< 0.001 | 4 | 355 | if min(col) == 0
|
< 0.001 | 4 | 356 | inset(1) = def_pos(1);
|
< 0.001 | 4 | 357 | outerpos(3) = outerpos(1) + outerpos(3);
|
< 0.001 | 4 | 358 | outerpos(1) = 0;
|
< 0.001 | 4 | 359 | end
|
< 0.001 | 4 | 360 | if min(row) == 0
|
< 0.001 | 1 | 361 | inset(2) = def_pos(2);
|
< 0.001 | 1 | 362 | outerpos(4) = outerpos(2) + outerpos(4);
|
< 0.001 | 1 | 363 | outerpos(2) = 0;
|
< 0.001 | 4 | 364 | end
|
< 0.001 | 4 | 365 | if max(col) == nCols - 1
|
< 0.001 | 4 | 366 | inset(3) = max(0, 1 - def_pos(1) - def_pos(3));
|
< 0.001 | 4 | 367 | outerpos(3) = 1 - outerpos(1);
|
< 0.001 | 4 | 368 | end
|
< 0.001 | 4 | 369 | if max(row) == nRows - 1
|
< 0.001 | 1 | 370 | inset(4) = max(0, 1 - def_pos(2) - def_pos(4));
|
< 0.001 | 1 | 371 | outerpos(4) = 1 - outerpos(2);
|
< 0.001 | 4 | 372 | end
|
| | 373 |
|
| | 374 | % compute inner position
|
< 0.001 | 4 | 375 | position = [outerpos(1 : 2) + inset(1 : 2), ...
|
| 4 | 376 | outerpos(3 : 4) - inset(1 : 2) - inset(3 : 4)];
|
| | 377 |
|
< 0.001 | 4 | 378 | end
|
< 0.001 | 4 | 379 | end
|
< 0.001 | 4 | 380 | end
|
| | 381 |
|
| | 382 | % kill overlapping siblings if mnp specifier was used:
|
< 0.001 | 4 | 383 | nextstate = ancestorFigure.NextPlot;
|
| | 384 |
|
< 0.001 | 4 | 385 | if strncmp(nextstate, 'replace', 7)
|
| | 386 | nextstate = 'add';
|
< 0.001 | 4 | 387 | elseif strncmp(nextstate, 'new', 3)
|
| | 388 | killSiblings = 0;
|
< 0.001 | 4 | 389 | end
|
| | 390 |
|
< 0.001 | 4 | 391 | if killSiblings
|
< 0.001 | 4 | 392 | if delayDestroy
|
| | 393 | ancestorFigure.NextPlot = 'replace';
|
| | 394 | return
|
< 0.001 | 4 | 395 | end
|
< 0.001 | 4 | 396 | hasDeleted = false;
|
0.004 | 4 | 397 | sibs = datasiblings(parent);
|
< 0.001 | 4 | 398 | newcurrent = [];
|
< 0.001 | 4 | 399 | for i = 1 : length(sibs)
|
| | 400 | % Be aware that handles in this list might be destroyed before
|
| | 401 | % we get to them, because of other objects' DeleteFcn callbacks...
|
0.002 | 6 | 402 | if isSubplotCandidate(sibs(i))
|
< 0.001 | 6 | 403 | units = sibs(i).Units;
|
| | 404 |
|
< 0.001 | 6 | 405 | if isa(sibs(i),'matlab.graphics.chart.Chart') ...
|
| | 406 | && ~(isa(sibs(i),'matlab.graphics.chart.internal.SubplotPositionableChart') || ...
|
| | 407 | isa(sibs(i),'matlab.graphics.chart.internal.PositionableChartWithAxes'))
|
| | 408 | % when existing chart replaced a subplot, use
|
| | 409 | % inner position of the axes it replaced when
|
| | 410 | % checking for matching/overlapping.
|
| | 411 | if isappdata(sibs(i),'SubplotPosition')
|
| | 412 | sibpos = getappdata(sibs(i),'SubplotPosition');
|
| | 413 | if length(sibpos) < 4
|
| | 414 | sibpos = sibs(i).OuterPosition;
|
| | 415 | end
|
| | 416 | else
|
| | 417 | if all(sibs(i).OuterPosition == [0,0,1,1]) && ...
|
| | 418 | ~explicitPosition && all(nRows == 1) && all(nCols == 1)
|
| | 419 | % special case to make subplot(1,1,1) select
|
| | 420 | % (and not clobber) a [0,0,1,1] full-container chart.
|
| | 421 | % Even though the requested subplot's position
|
| | 422 | % doesn't match the existing Chart's
|
| | 423 | % OuterPosition, pretend the existing
|
| | 424 | % chart was positioned at the exact location
|
| | 425 | % of the requested subplot
|
| | 426 | sibpos = position;
|
| | 427 | else
|
| | 428 | % otherwise, compare against the chart's
|
| | 429 | % OuterPosition when deciding if we should
|
| | 430 | % clobber existing chart with the incoming subplot
|
| | 431 | sibpos = sibs(i).OuterPosition;
|
| | 432 |
|
| | 433 | end
|
| | 434 | end
|
| | 435 |
|
< 0.001 | 6 | 436 | else
|
< 0.001 | 6 | 437 | sibpos = sibs(i).InnerPosition;
|
< 0.001 | 6 | 438 | end
|
| | 439 | % If a legend or colorbar has resized the axes, use the original axes
|
| | 440 | % position as the "Position" property:
|
< 0.001 | 6 | 441 | if ~explicitPosition
|
0.001 | 6 | 442 | if isappdata(sibs(i), 'LegendColorbarExpectedPosition') && ...
|
| | 443 | isequal(getappdata(sibs(i), 'LegendColorbarExpectedPosition'), get(sibs(i), 'InnerPosition'))
|
| | 444 | sibinset = getappdata(sibs(i), 'LegendColorbarOriginalInset');
|
| | 445 | if isempty(sibinset)
|
| | 446 | % during load the appdata might not be present
|
| | 447 | sibinset = get(sibs(i).Parent, 'DefaultAxesLooseInset');
|
| | 448 | end
|
| | 449 | sibinset = offsetsInUnits(sibs(i), sibinset, 'normalized', get(sibs(i), 'Units'));
|
| | 450 | if strcmpi(sibs(i).ActivePositionProperty, 'position')
|
| | 451 | pos = sibs(i).InnerPosition;
|
| | 452 | loose = sibs(i).LooseInset;
|
| | 453 | opos = getOuterFromPosAndLoose(pos, loose, get(sibs(i), 'Units'));
|
| | 454 | if strcmp(sibs(i).Units, 'normalized')
|
| | 455 | sibinset = [opos(3 : 4), opos(3 : 4)] .* sibinset;
|
| | 456 | end
|
| | 457 | sibpos = [opos(1 : 2) + sibinset(1 : 2), opos(3 : 4) - sibinset(1 : 2) - sibinset(3 : 4)];
|
| | 458 | end
|
< 0.001 | 6 | 459 | end
|
< 0.001 | 6 | 460 | end
|
< 0.001 | 6 | 461 | if ~strcmp(units, 'normalized')
|
| | 462 | sibpos = hgconvertunits(ancestorFigure, sibpos, units, 'normalized', parent);
|
< 0.001 | 6 | 463 | end
|
< 0.001 | 6 | 464 | intersect = 1;
|
< 0.001 | 6 | 465 | if ((position(1) >= sibpos(1) + sibpos(3) - tol) || ...
|
| 6 | 466 | (sibpos(1) >= position(1) + position(3) - tol) || ...
|
| 6 | 467 | (position(2) >= sibpos(2) + sibpos(4) - tol) || ...
|
| 6 | 468 | (sibpos(2) >= position(2) + position(4) - tol))
|
< 0.001 | 6 | 469 | intersect = 0;
|
< 0.001 | 6 | 470 | end
|
< 0.001 | 6 | 471 | if intersect
|
| | 472 | % position is the proposed position of an axes, and
|
| | 473 | % sibpos is the current position of an existing axes.
|
| | 474 | % Since the bounding boxes of position and sibpos overlap,
|
| | 475 | % we must determine whether to delete the sibling sibs(i)
|
| | 476 | % whose normalized position is sibpos.
|
| | 477 |
|
| | 478 | % First of all, we check whether we must kill the sibling
|
| | 479 | % "no matter what."
|
| | 480 | if (killSiblings == 2)
|
| | 481 | if ~hasDeleted
|
| | 482 | hasDeleted = true;
|
| | 483 | % Notify the editor that an axes is being deleted
|
| | 484 | matlab.graphics.internal.clearNotify(ancestorFigure, 'delete');
|
| | 485 | end
|
| | 486 |
|
| | 487 | delete(sibs(i));
|
| | 488 |
|
| | 489 | % If the proposed and existing axes overlap exactly, we do
|
| | 490 | % not kill the sibling. Rather we shall ensure later that
|
| | 491 | % this sibling axes is set as the 'CurrentAxes' of its
|
| | 492 | % ancestorFigure.
|
| | 493 |
|
| | 494 | % Next we check for a partial overlap.
|
| | 495 | elseif (any(abs(sibpos - position) > tol))
|
| | 496 | % The proposed and existing axes partially overlap.
|
| | 497 | % Since the proposed and existing axes could each be
|
| | 498 | % "grid-generated" or "explicitly-specified", we must
|
| | 499 | % consider four possibilities for the overlap of
|
| | 500 | % "proposed" vs. "existing", i.e.
|
| | 501 | % (1) "grid-generated" vs. "grid-generated"
|
| | 502 | % (2) "grid-generated" vs. "explicitly-specified"
|
| | 503 | % (3) "explicitly-specified" vs. "grid-generated"
|
| | 504 | % (4) "explicitly-specified" vs. "explicitly-specified"
|
| | 505 |
|
| | 506 | % If the position of the proposed axes is
|
| | 507 | % "explicitly-specified", then the only condition that
|
| | 508 | % avoids killing the sibling is an exact overlap.
|
| | 509 | % However, we know that the overlap is partial.
|
| | 510 | if (explicitPosition)
|
| | 511 | if ~hasDeleted
|
| | 512 | hasDeleted = true;
|
| | 513 | % Notify the editor that an axes is being deleted
|
| | 514 | matlab.graphics.internal.clearNotify(ancestorFigure, 'delete');
|
| | 515 | end
|
| | 516 | delete(sibs(i));
|
| | 517 | else
|
| | 518 | % We know that the position of the proposed axes is
|
| | 519 | % "grid-generated".
|
| | 520 |
|
| | 521 | grid = getappdata(parent, 'SubplotGrid');
|
| | 522 | % The SubplotGrid maintains an array of axes
|
| | 523 | % handles, one per grid location. Axes that span
|
| | 524 | % multiple grid locations do not store handles in
|
| | 525 | % the SubplotGrid.
|
| | 526 |
|
| | 527 | if isempty(grid) || ~any(grid(:) == sibs(i)) || ...
|
| | 528 | size(grid, 1) ~= nRows || size(grid, 2) ~= nCols || ...
|
| | 529 | ~isscalar(row) || ~isscalar(col)
|
| | 530 | % If the sibling cannot be found in the grid, we
|
| | 531 | % kill the sibling. Otherwise, the proposed and
|
| | 532 | % existing axes are "grid-generated". If we
|
| | 533 | % are changing the size of the grid, we kill
|
| | 534 | % the sibling. Otherwise, "plotId" may be a
|
| | 535 | % vector of multiple grid locations, which
|
| | 536 | % causes a partial overlap between the proposed
|
| | 537 | % and existing axes, so we kill the sibling.
|
| | 538 |
|
| | 539 | % This check recognizes that there may be
|
| | 540 | % labels, colorbars, legends, etc. attached to
|
| | 541 | % the existing axes that have affected its
|
| | 542 | % position. In such a case, we do not kill the
|
| | 543 | % sibling.
|
| | 544 | if ~hasDeleted
|
| | 545 | hasDeleted = true;
|
| | 546 | % Notify the editor that an axes is being deleted
|
| | 547 | matlab.graphics.internal.clearNotify(ancestorFigure, 'delete');
|
| | 548 | end
|
| | 549 | delete(sibs(i));
|
| | 550 | end
|
| | 551 | end
|
| | 552 | end
|
| | 553 | % if this axes overlaps the other one exactly then
|
| | 554 | if ~isempty(newcurrent) && isgraphics(newcurrent)
|
| | 555 | delete(newcurrent);
|
| | 556 | end
|
| | 557 | newcurrent = sibs(i);
|
| | 558 | if ~isempty(pvpairs) && isvalid(newcurrent)
|
| | 559 | set(newcurrent, pvpairs{:});
|
| | 560 | end
|
< 0.001 | 6 | 561 | end
|
< 0.001 | 6 | 562 | end
|
< 0.001 | 6 | 563 | end
|
< 0.001 | 4 | 564 | if ~isempty(newcurrent) && isgraphics(newcurrent)
|
| | 565 | ancestorFigure.CurrentAxes = newcurrent;
|
| | 566 | createAxis = false;
|
| | 567 | matlab.graphics.internal.markFigure(newcurrent);
|
< 0.001 | 4 | 568 | end
|
< 0.001 | 4 | 569 | ancestorFigure.NextPlot = nextstate;
|
< 0.001 | 4 | 570 | end
|
| | 571 |
|
< 0.001 | 4 | 572 | if isa(parent,'matlab.graphics.layout.Layout')
|
| | 573 | lay=parent;
|
| | 574 | parent=lay.Parent;
|
| | 575 | delete(lay)
|
< 0.001 | 4 | 576 | elseif isa(parent,'matlab.graphics.Graphics') && ...
|
| 4 | 577 | isa(parent,'matlab.ui.internal.mixin.CanvasHostMixin') && ...
|
| 4 | 578 | isvalid(parent)
|
0.007 | 4 | 579 | objs = findall(parent, '-depth', 1, {'-isa','matlab.graphics.layout.Layout'});
|
< 0.001 | 4 | 580 | delete(objs);
|
< 0.001 | 4 | 581 | end
|
| | 582 |
|
| | 583 | % create the axes:
|
< 0.001 | 4 | 584 | if createAxis
|
< 0.001 | 4 | 585 | if strcmp(nextstate, 'new') && ~explicitParent
|
| | 586 | parent = figure;
|
| | 587 | ancestorFigure = parent;
|
< 0.001 | 4 | 588 | end
|
0.102 | 4 | 589 | ax = axes('Units', 'normalized', 'InnerPosition', position, ...
|
| 4 | 590 | 'LooseInset', inset, 'Parent', parent);
|
| | 591 | % TODO: Get axes to accept position args on command line
|
< 0.001 | 4 | 592 | ax.Units = get(ancestorFigure, 'DefaultAxesUnits');
|
< 0.001 | 4 | 593 | if useAutoLayout
|
0.039 | 4 | 594 | addAxesToGrid(ax, nRows, nCols, row, col, position, plotId);
|
| | 595 | else
|
| | 596 | addNonGridAxes(ax,position);
|
< 0.001 | 4 | 597 | end
|
< 0.001 | 4 | 598 | if ~isempty(pvpairs)
|
| | 599 | set(ax, pvpairs{:});
|
< 0.001 | 4 | 600 | end
|
| | 601 | elseif moveAxis && ~preventMove
|
| | 602 |
|
| | 603 | % moving an existing axes/chart into a subplot layout.
|
| | 604 |
|
| | 605 | %first, remove h from any pre-existing subplot
|
| | 606 | matlab.graphics.internal.removeAxesFromGrid(h.Parent, h);
|
| | 607 | ax = h;
|
| | 608 | units = h.Units;
|
| | 609 |
|
| | 610 | % Some Charts position by outer position only & don't support
|
| | 611 | % insets. Don't modify position, just use the position of the
|
| | 612 | % outgoing subplot, as set by swapaxes.
|
| | 613 | if ~isa(h,'matlab.graphics.chart.Chart') %case for axes/polaraxes
|
| | 614 | set(h, 'Units', 'normalized', 'InnerPosition', position, ...
|
| | 615 | 'LooseInset', inset, 'Parent', parent);
|
| | 616 | elseif isa(h,'matlab.graphics.chart.internal.SubplotPositionableChart') || ...
|
| | 617 | isa(h,'matlab.graphics.chart.internal.PositionableChartWithAxes')
|
| | 618 | outerposition = [position(1:2) - inset(1:2), position(3:4) + inset(1:2) + inset(3:4)];
|
| | 619 | set(h, 'Units', 'normalized', 'InnerPosition', position, ...
|
| | 620 | 'MaxInsetForSubplotCell', inset, ...
|
| | 621 | 'SubplotCellOuterPosition', outerposition, 'Parent', parent);
|
| | 622 | else %orange chart that has been positioned in grid by swapaxes
|
| | 623 | set(h,'Parent',parent);
|
| | 624 | end
|
| | 625 |
|
| | 626 |
|
| | 627 |
|
| | 628 | h.Units = units;
|
| | 629 | if ~isempty(pvpairs)
|
| | 630 | set(h, pvpairs{:});
|
| | 631 | end
|
| | 632 | if useAutoLayout
|
| | 633 | addAxesToGrid(ax, nRows, nCols, row, col, position, plotId);
|
| | 634 | else
|
| | 635 | addNonGridAxes(ax,position);
|
| | 636 | end
|
| | 637 |
|
| | 638 | else
|
| | 639 | % this should only happen with subplot(H)
|
| | 640 | ax = ancestorFigure.CurrentAxes;
|
< 0.001 | 4 | 641 | end
|
| | 642 | % return identifier, if requested:
|
< 0.001 | 4 | 643 | if(nargout > 0)
|
| | 644 | theAxis = ax;
|
< 0.001 | 4 | 645 | end
|
| | 646 |
|
< 0.001 | 4 | 647 | end
|
Other subfunctions in this file are not included in this listing.