본문 바로가기

Enginius/Matlab

Get width and height automatically for SUBPLOT (get_wh4subplot)

하나의 figure에 여러 subfigure를 그려야 할 때 subplot을 자주 사용하게 된다.

subplot의 문법은 subplot(h, w, i)이다. 여기서 h와 w는 height와 width에 들어갈 figure의 수고, i는 몇 번째 subfigure에 그림을 그릴지 정한다.

문제는 내가 n개의 subfigure를 그리려 할 때, h와 w를 정하는데 있다. fix된 n이라면 상관 없겠지만, 실험에 따라 n이 변할 때 이를 설정하는 것은 의외고 귀찮은 일이다. 그래서 이를 자동으로 구하는 함수를 구현했다.

원리는 간단한다. 주어진 n의 공약수를 모두 구한 후에, sqrt(n) 사이에 있는 값을 사용한다. 예를 들어 n이 20일 때, 4*5로 나타내겠다는 것이다. 40의 경우는 5*8이 된다.

내 생각엔 나름 reasonable하다.

 

function [subplot_h, subplot_w] ...
    = get_wh4subplot(n)
divs = divisor(n);
sqrt_n = sqrt(n);
for i = 1:length(divs)
    curr_div = divs(i);
    if curr_div > sqrt_n
        subplot_w = curr_div;
        break;
    end
end
subplot_h = n/subplot_w;

function d = divisor(n)
%% divisor : provides a list of integer divisors of a number.
% divisor(n) : row vector of all distinct divisors of a positive integer N,
%               including 1 and N.
%
% Remark:
%   This function uses the default factor() routine in Matlab and hence is
% limited to input values upto 2^32. However if factor() routine does get
% updated for larger integers, this function will still work fine.
%   Using factor() provides a significant speed improvement over manually
% seaching for the each divisor of n.
%
% Example:
%   a = divisor(12);
%   returns -> a = [1, 2, 3, 4, 6, 12];
%
% See Also:
%   factor, primes

% Author: Yash Kochar ( yashkochar@yahoo.com )
% Last modified: 21st June 2009
%-------------------------------------------------------------------------------

%% Input error check :
%   Check whether input is positive integer and scalar.
if ~isscalar(n)
    error('divisor:NonScalarInput','Input must be a scalar.');
end
if (n < 1) || (floor(n) ~= n)
  error('divisor:PositiveIntegerOnly', 'Input must be a positive integer.');
end

%% Find prime factors of number :
pf = factor(n);         % Prime factors of n
upf = unique(pf);       % Unique

%% Calculate the divisors
d = upf(1).^(0:1:sum(pf == upf(1)))';
for f = upf(2:end)
    d = d*(f.^(0:1:sum(pf == f)));
    d = d(:);
end
d = sort(d)';   % To further improve the speed one may remove this sort command
                %   Just remember to take the transpose of "d" to get a result
                %   as a row vector instead of a column vector.

'Enginius > Matlab' 카테고리의 다른 글

Simple Loop Indicator  (0) 2013.11.24
Reduce the Gap between SUBPLOT (subaxes)  (3) 2013.10.18
Split structured TXT files (strsplit)  (0) 2013.09.29
Use Thread in Matlab by mex-compile C code  (0) 2013.09.29
Control Pioneer 3dx with MATLAB  (0) 2013.08.21