Newer
Older
function varargout=hist2(varargin)
%HIST2 Two-dimensional histogram.
% P=HIST2(X) bins the two-dimensional density of X(i) and
% X(i+1) into a 10x10 equally spaced matrix and returns it
% in P.
%
% P=HIST2(X,Y) bins the two-dimensional density of X(i) and
% Y(i) into a 10x10 equally spaced matrix and returns it
% in P.
%
% P=HIST2(X,K,L), where K and L are scalars, uses K bins and
% a lag L.
%
% [P,J]=HIST2(...) returns the matrix P and the two-dimensional
% vector J containing the two-dimensional density matrix and the
% bin location for X (and Y).
%
% HIST2(...) without any output arguments produces a histogram plot.
%
% HIST2(...,'gui') creates a GUI for interactively changing
% of the parameters (not yet implemented).
%
% Examples: x = randn(10000,1);
% hist2(x)
%
% See also HIST, HISTN, BAR3, MI.
% Copyright (c) 2008-2009
% Norbert Marwan, Potsdam Institute for Climate Impact Research, Germany
% http://www.pik-potsdam.de
%
% Copyright (c) 2002-2008
% Andre Sitz, Norbert Marwan, Potsdam University, Germany
% http://www.agnld.uni-potsdam.de
%
% $Date$
% $Revision$
%
% $Log$
% Revision 1.12 2007/12/20 16:26:05 marwan
% changed gpl splash behaviour
%
% Revision 1.11 2007/05/25 13:02:48 marwan
% some comments added
%
% Revision 1.10 2006/07/04 14:05:08 marwan
% lag = zero allowed
%
% Revision 1.9 2004/11/10 07:05:37 marwan
% initial import
%
%
% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License
% as published by the Free Software Foundation; either version 2
% of the License, or any later version.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% check the input
error(nargchk(1,5,nargin));
if nargout>2, error('Too many output arguments'), end
varargin{6}=[];
nogui=1;
lag=[];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% read the input
x=varargin{1};
if isempty(varargin{2}) | ~isnumeric(varargin{2}), y=x; lag=[];
else, y=double(varargin{2}); end
i_double=find(cellfun('isclass',varargin,'double'));
i_char=find(cellfun('isclass',varargin,'char'));
if (isnumeric(varargin{2}) & max(size(varargin{2}))==1) | ~isnumeric(varargin{2})
y=x;
if ~isempty(varargin{i_double(2)}), nbin=varargin{i_double(2)}; else nbin=10; end
if ~isempty(varargin{i_double(3)}), lag=varargin{i_double(3)}; else lag=1; end
else
if ~isempty(varargin{i_double(3)}), nbin=varargin{i_double(3)}; else nbin=10; end
if ~isempty(varargin{i_double(4)}), lag=varargin{i_double(4)}; else if isempty(lag), lag=0; end, end
end
if ~isempty(i_char)
if strcmpi(varargin{i_char(1)}(1:3),'gui'), nogui=0; end
end
if ~(prod(double(size(y)==size(x)))), error('Both vectors must have the same size.'), end
if size(x,1)<size(x,2), x=x';end
if size(y,1)<size(y,2), y=y';end
x=x(:,1); y=y(:,1);
%x=x(:); y=y(:);
% normalise the value range to [0 1)
x1 = (x - min(x)) / max(x - min(x)) - eps;
y1 = (y - min(y)) / max(y - min(y)) - eps;
if length(x)<=lag, lag=length(x)-1; warning(['Lag is too large. Using ',num2str(lag),' instead.']), end
% this is the main trick: put the first data to values [1:1:nbin] and the second data to [nbin:nbin:nbin^2]
temp = fix(x1(1:(end-lag)) * nbin) + (fix(y1((lag+1):end) * nbin)) * nbin;
p=histc(temp,0:(nbin^2-1))';
p2=reshape(p,nbin,nbin)/length(x);
minx = min(min(x)); maxx = max(max(x));
if minx == maxx, minx = minx - floor(nbin/2) - 0.5; maxx = maxx + ceil(nbin/2) - 0.5; end
miny = min(min(y)); maxy = max(max(y));
if miny == maxy, miny = miny - floor(nbin/2) - 0.5; maxy = maxy + ceil(nbin/2) - 0.5; end
bins(1,:)=minx:(maxx-minx)/(nbin-1):maxx+eps;
bins(2,:)=miny:(maxy-miny)/(nbin-1):maxy+eps;
if nargout==0
bar3(bins(2,:),p2')
dhy=bins(2,2)-bins(2,1);
set(gca,'xlim',[0 nbin+1-.1],'ylim',[bins(2,1)-dhy bins(2,end)+dhy])
hx=get(gca,'xtick'); dhx=diff(hx);
set(gca,'xtick',[1:dhx(1):nbin+1])
if dhx>1
tx=num2str(fix(100*[bins(1,1):(bins(1,end)-bins(1,1))/(length(hx)-1):bins(1,end)]')/100);
else
tx=num2str(fix(100*[bins(1,:)]')/100);
end
set(gca,'xticklabel',tx)
xlabel('x'), ylabel('y')
elseif nargout==1