function [n, xout] = histx(varargin)
% A wrapper for hist that picks the "ideal" number of bins to use if
% unspecified.
%
% N = HISTX(Y) bins the elements of Y into M equally spaced containers and
% returns the number of elements in each container. If Y is a matrix, HIST
% works down the columns. The value of M is the middle (median) value of
% the optimal number of bins calculated using the Freedman-Diaconis, Scott
% and Sturges methods. See below for further information on these methods.
%
% N = HISTX(Y,M), where M is a scalar, uses M bins. (This is identical to
% N = HIST(Y,M).)
%
% N = HISTX(Y, X), where X is a vector, returns the distribution of Y among
% bins with centers specified by X. The first bin includes data between
% -inf and the first center and the last bin includes data between the last
% bin and inf. Note: Use HISTC if it is more natural to specify bin edges
% instead. (This is identical to N = HIST(Y,X).)
%
% N = HISTX(Y, METHOD), where METHOD is a string chooses the number of bins
% as follows:
%
% 'fd': The Freedman-Diaconis method, based upon the inter-quartile range
% and number of data, is used.
% 'scott': The Scott method, based upon the sample standard deviation and
% nnumber of data, is used.
% 'sturges': The Sturges method, based upon the number of data, is used.
% 'middle': All three methods are tried, and the middle value is used.
%
% N = HISTX(Y, [], MINIMUM), where MINIMUM is a numeric scalar, defines the
% smallest acceptable number of bins.
%
% N = HISTX(Y, [], [], MAXIMUM), where MAXIMUM is a numeric scalar, defines the
% largest acceptable number of bins.
%
% HISTX(...) without output arguments produces a histogram bar plot of the
% results. The bar edges on the first and last bins may extend to cover the
% min and max of the data unless a matrix of data is supplied.
%
% HISTX(Y, 'all') produces three histograms in a new figure window, drawn
% with the number of bins calculated using each of the three methods.
%
% HISTX(AX, ...) plots into AX instead of GCA.
%
% Notes:
% 1. When the method chosen is 'all', any axes inputted will be ignored
% with a warning. Likewise for output arguments.
%
% 2. References for the methods can be found in the help page for
% CALCNBINS.
%
% Examples:
% y = randn(10000,1);
% histx(y)
% histx(y, 'all')
%
% See also: CALCNBINS, HIST.
%
% $ Author: Richard Cotton $ $ Date: 2008/08/28 $ $ Version 1.1 $
% Check there is at least one input, and see if the first input is an axis.
error(nargchk(1,inf,nargin,'struct'));
[cax,args,nargs] = axescheck(varargin{:});
plotall = false;
y = args{1};
% If the number of bins wasn't specified, calculate it using calcnbins.
if nargs < 4 || isempty(args{4})
args{4} = []; % this also sets missing arguments before this positon to [].
end
if ~isempty(args{2}) && isnumeric(args{2})
nbins = args{2};
else
nbins = calcnbins(y, args{2}, args{3}, args{4});
if ischar(args{2}) && strcmpi(args{2}, 'all')
plotall = true;
end
end
% Plot the histogram(s)
if plotall
if nargout > 0
warning('histx:ignoreargout', 'No arguments will be returned when the method is "all".');
end
if ~isempty(cax)
warning('histx:ignoreaxes', 'The input axes are ignored when the method is "all".');
end
n = [];
xout = [];
figure();
subplot(3, 1, 1); hist(y, nbins.fd);
title('Freedman-Diaconis'' method');
subplot(3, 1, 2); hist(y, nbins.scott);
title('Scott''s method');
subplot(3, 1, 3); hist(y, nbins.sturges);
title('Sturges'' method');
else
if nargout==0
if isempty(cax)
hist(y, nbins);
else
hist(cax, y, nbins);
end
else
if isempty(cax)
[n, xout] = hist(y, nbins);
else
[n, xout] = hist(cax, y, nbins);
end
end
end