%PLOTR Plot error curves
%
%   H = PLOTR(E,LINEWIDTH,S,FONTSIZE,OPTIONS)
%
% INPUT
%   E          Structure containing error curves (see e.g. CLEVAL)
%   LINEWIDTH  Line width, < 5 (default 1.5)
%   S          Plot strings
%   FONTSIZE   Font size, >= 5 (default 5)
%   OPTIONS    Character strings:
%              'nolegend' suppresses the legend plot
%              'errorbar' add errorbars to the plot
%
% OUTPUT
%   H          Array of graphics handles
%
% DESCRIPTION
% Various evaluation routines like CLEVAL return an error curves packed in a
% structure E. PLOTR uses the information stored in E to plot the curves. The 
% remaining parameters may be given in an arbitrary order.
%
% E may contain the following fields (E.ERROR is obligatory):
%   E.ERROR    C x N matrix of error values for C methods at N points
%   E.XVALUES  C x N matrix of measurement points; if 1 x N, it is used for 
%                all C curves
%   E.TITLE    the title of the plot
%   E.XLABEL   the label for the x-axis
%   E.YLABEL   the label for the y-axis
%   E.NAMES    a string array of C names used for creating a LEGEND
%   E.PLOT     the plot command in a string: 'plot', 'semilogx', 'semilogy' 
%                or 'loglog'
%   E.STD      C x N matrix with standard deviations of the mean error values
%                which are plotted if ERRBAR == 1
%
% These fields are automatically set by a series of commands like CLEVAL,
% CLEVALF, ROC and REJECT.
%
% The legend generated by PLOTR can be removed by LEGEND OFF. A new legend
% may be created by the LEGEND command using the handles stored in H.
%
% EXAMPLES
% See PREX_CLEVAL
%
% SEE ALSO
% CLEVAL, CLEVALF, ROC, REJECT

% Copyright: R.P.W. Duin, duin@ph.tn.tudelft.nl
% Faculty of Applied Sciences, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands

% $Id: plotr.m,v 1.11 2004/02/26 19:49:45 davidt Exp $

function handle = plotr(varargin)

	prtrace(mfilename);
	
	% Set default parameter values.

	e         = [];
	s         = [];
	linewidth = 1.5;
	nolegend  = 0;
	fontsize  = 16;
	errbar    =  0;
	ss = char('k-','r-','b-','m-','k--','r--','b--','m--');
	ss = char(ss,'k-.','r-.','b-.','m-.','k:','r:','b:','m:');

	% The input is so flexible, that we have to do a lot of work...

	for j = 1:nargin
		p = varargin{j};
		if (isstruct(p))
			e = p;
		elseif (isstr(p)) & (strcmp(p,'errorbar') | strcmp(p,'ERRORBAR'))
			errbar = 1;
		elseif (isstr(p)) & (strcmp(p,'nolegend') | strcmp(p,'NOLEGEND'))
			nolegend = 1;
		elseif (isstr(p))
			s = p;
		elseif (length(p) == 1) & (p < 5)
			linewidth = p;
		elseif (length(p) == 1) & (p >= 5)
			fontsize = p;
		end
	end

	% Check if we have the required data and data fields.

	if (isempty(e))
		error('Error structure not specified.')
	end

	if (~isfield(e,'error'))
		error('Input structure should contain the ''error''-field.');
	end

	n = size(e.error,1);

	if (~isfield(e,'xvalues'))
		e.xvalues = [1:length(e.error)];
	end
	if (size(e.xvalues,1) == 1)
		e.xvalues = repmat(e.xvalues,n,1);
	end

	if (isempty(s))
		s = ss(1:n,:);
	end
	if (size(s,1) == 1) & (n > 1)
		s = repmat(s,n,1);
	end
	if (size(s,1) < n)
		error('Insufficient number of plot strings.')
	end

	if (~isfield(e,'plot'))
		e.plot = 'plot';
	end

	if errbar
		if (isfield(e,'std'))
			ploterrorbar = 1;
		else
			error('No standard deviations given, so errorbars cannot be plotted')
		end
	else
		ploterrorbar = 0;
	end
	
	% We can now start making the plot.

	clf; h = [];
	for j = 1:n
		if ploterrorbar
			hh = feval('errorbar',e.xvalues(j,:),e.error(j,:),e.std(j,:),deblank(s(j,:)));
		else
			hh = feval(e.plot,e.xvalues(j,:),e.error(j,:),deblank(s(j,:)));
		end
		set(hh,'linewidth',linewidth); hold on; h = [h hh];
	end
		
	% That was basically it, now we only have to beautify it.

	errmax = max(e.error(:));
	set(gca,'fontsize',fontsize);

	if (isfield(e,'xlabel')), xlabel(e.xlabel); end
	if (isfield(e,'ylabel')), ylabel(e.ylabel); end
	if (isfield(e,'title')),  title(e.title);   end
	if (isfield(e,'names')) & (~isempty(e.names) & (~nolegend))
		legend(h,e.names);
	end

	% A lot of work to make the scaling of the y-axis nice.

	if (errmax > 0.6)
		errmax = ceil(errmax*5)/5;
		yticks = [0:0.2:errmax];
	elseif (errmax > 0.3)
		errmax = ceil(errmax*10)/10;
		yticks = [0:0.1:errmax];
	elseif (errmax > 0.2)
		errmax = ceil(errmax*20)/20;
		yticks = [0:0.05:errmax];
	elseif (errmax > 0.1)
		errmax = ceil(errmax*30)/30;
		yticks = [0:0.03:errmax];
	elseif (errmax > 0.06)
		errmax = ceil(errmax*50)/50;
		yticks = [0:0.02:errmax];
	elseif (errmax > 0.03)
		errmax = ceil(errmax*100)/100;
		yticks = [0:0.01:errmax];
	else
		yticks = [0:errmax/3:errmax];
	end

		% atttempt to beautify plot
	if (e.xvalues(end) >= 2)
		%DXD
		%axis([e.xvalues(1)-1,e.xvalues(end)+1,0,errmax]);
		axis([min(min(e.xvalues)),max(max(e.xvalues)),0,errmax]);
	elseif (e.xvalues(1) == 0)
		axis([-0.003,e.xvalues(end),0,errmax]);
	end
		
	set(gca,'ytick',yticks);
	
	hold off; if (nargout > 0), handle = h; end;
	
	return
