function H = vl_tightsubplot(varargin) % VL_TIGHTSUBPLOT Tiles axes without wasting space % H = VL_TIGHTSUBPLOT(K,P) returns an handle to the P-th axis in a % regular grid of K axes. The K axes are numbered from left to right % and from top to bottom. The function operates similarly to % SUBPLOT(), but by default it does not put any margin between % axes. This is done by tiling the axes inner box rather than the % axes outer box. % % H = VL_TIGHTSUBPLOT(M,N,P) retursn an handle to the P-th axes in a % regular subdivision with M rows and N columns. % % VL_TIGHTSUBPLOT() accepts the following options: % % Margin:: [0] % MarginLeft:: [0] % MarginRight:: [0] % MarginTop:: [0] % MarginBottom:: [0] % Set the axes inner box margin, either uniformly in all % directions, or specifically to the left, right, top or bottom. % % Box:: [0] % If set to 'outer', tile the axes outer box, thus protecting % title and labels. Unfortunately this usually produces % unnecesarily large margins. % % Spacing:: [0] (legacy option) % Set extra spacing between axes. The space is added between the % inner or outer boxes, depending on the setting below. % % REMARK. While SUBPLOT kills any pre-existing axes that overalps a % new one, this function does not. % % See also: SUBPLOT(), VL_HELP(). % Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson. % All rights reserved. % % This file is part of the VLFeat library and is made available under % the terms of the BSD license (see the COPYING file). % margins ml = 0 ; mr = 0 ; mt = 0 ; mb = 0 ; use_outer=0 ; % -------------------------------------------------------------------- % Parse arguments % -------------------------------------------------------------------- K = varargin{1} ; p = varargin{2} ; N = ceil(sqrt(K)) ; M = ceil(K/N) ; a=3 ; NA = length(varargin) ; if NA > 2 if isa(varargin{3},'char') % Called with K and p else % Called with M,N and p a = 4 ; M = K ; N = p ; p = varargin{3} ; end end for a=a:2:NA opt=lower(varargin{a}) ; arg=varargin{a+1} ; switch opt case 'margin' mt = arg ; mb = arg ; ml = arg ; mr = arg ; case 'marginleft' ml = arg ; case 'marginright' mr = arg ; case 'margintop' mt = arg ; case 'marginbottom' mb = arg ; case 'spacing' mt = arg/2 ; mb = arg/2 ; ml = arg/2 ; mr = arg/2 ; case 'box' switch lower(arg) case 'inner' use_outer = 0 ; case 'outer' use_outer = 1 ; otherwise error(['Box is either ''inner'' or ''outer''']) ; end otherwise error(['Uknown parameter ''', varargin{a}, '''.']) ; end end % -------------------------------------------------------------------- % Check the arguments % -------------------------------------------------------------------- [j,i]=ind2sub([N M],p) ; i=i-1 ; j=j-1 ; pos = [ j * 1/N + ml,... 1 - i * 1/M - 1/M + mb,... 1/N - ml - mr, ... 1/M - mt - mb] ; switch use_outer case 0 H = findobj(gcf, 'Type', 'axes', 'Position', pos) ; if(isempty(H)) H = axes('Position', pos) ; else axes(H) ; end case 1 H = findobj(gcf, 'Type', 'axes', 'OuterPosition', pos) ; if(isempty(H)) H = axes('ActivePositionProperty', 'outerposition',... 'OuterPosition', pos) ; else axes(H) ; end end