function obj = plot_superpose(plots, axis_labels, title_str, props)
% plot_superpose - Multiple plot_abstract objects superposed on the same axis.
%
% Usage:
% obj = plot_superpose(plots, axis_labels, title_str, props)
%
% Parameters:
% plots: Cell array of plot_abstract or subclass objects.
% axis_labels: Cell array of axis label strings.
% title_str: Plot description string.
% props: A structure with any optional properties (passed to
% plot_abstract).
% noCombine: Do not auto-combine plots with same properties
% (default=0). This is especially important for plot_bars.
%
% Returns a structure object with the following fields:
% plot_abstract, plots
%
% Description:
% Subclass of plot_abstract. Contains multiple plot_abstract objects to be
% plotted on the same axis. This is different than the
% plot_abstract/superpose, where only using the same plot command is
% allowed. Here, each plot_abstract can have its own special plotting
% command. Subclasses of plot_abstract is also allowed here. The decorations
% comes from this object and not children plots. This behavior is different
% than plot_stack, where each plot has its own decorations. If you want each
% plot to have its own axis (e.g. an inset, or plot with multiple axis
% labels) then you should use plot_inset. For convenience, the props of
% first plot is inherited by plot_superpose objects. For instance, in the
% example below, the fixedSize property is used by plotFigure because
% it's in the first subplot.
%
% General operations on plot_superpose objects:
% plot_superpose - Construct a new plot_superpose object.
% plot - Plots this plot in the current axis. Abstract method,
% needs to be defined for each subclass.
%
% Additional methods:
% See methods('plot_superpose')
%
% Example:
% >> a_p = plot_abstract({[0 0], [1 2]}, {}, '', {}, 'plot',
% struct('fixedSize', [3 2]));
% >> a_p2 = plot_abstract(...)
% >> a_p3 = plot_abstract(...)
% >> plotFigure(plot_superpose({a_p1, a_p2, a_p3}))
%
% See also: plot_abstract/superpose, plot_superpose/plot
%
% $Id$
%
% Author: Cengiz Gunay <cgunay@emory.edu>, 2004/09/22
% Copyright (c) 2007 Cengiz Gunay <cengique@users.sf.net>.
% This work is licensed under the Academic Free License ("AFL")
% v. 3.0. To view a copy of this license, please look at the COPYING
% file distributed with this software or visit
% http://opensource.org/licenses/afl-3.0.php.
% TODO: decoration controls imposed by plot_stack is ignored!
if nargin == 0 % Called with no params
obj.plots = {};
obj = class(obj, 'plot_superpose', plot_abstract);
elseif isa(plots, 'plot_superpose') % copy constructor?
obj = plots;
else
if ~ exist('props', 'var')
props = struct;
end
if ~ exist('axis_labels', 'var')
axis_labels = [];
end
if ~ exist('title_str', 'var')
title_str = '';
end
if ~ iscell(plots)
plots = mat2cell(plots);
end
% Check if plots are of same kind to call preferred superposePlots method instead
plot_class = '';
plot_command = '';
superposable = true;
% replicate the first plot to pre-allocate the array
plot_array = plots{1};
for plot_num=1:length(plots)
% do not check if
if isfield(props, 'noCombine')
superposable = false;
break;
end
% check if same plot classes are used
if isempty(plot_class)
plot_class = class(plots{plot_num});
else
% break if different plot classes are combined
if ~strcmp(plot_class, class(plots{plot_num}))
superposable = false;
break;
end
end
% If same class, add to array
plot_array(plot_num) = plots{plot_num};
if strcmp(plot_class, 'plot_abstract') || strcmp(plot_class, 'plot_simple')
if isempty(plot_command)
plot_command = plots{plot_num}.command;
else
% break if different plot commands in plot_abstracts are combined
if ~strcmp(plot_command, plots{plot_num}.command)
superposable = false;
break;
end
end
end
end
% Leave the constructor and call superposePlots
if superposable
obj = superposePlots(plot_array);
return;
end
% plot_stack not allowed if not superposable
if isa(plots{1}, 'plot_stack')
error('Stacking using noCombine is not implemented with plot_stack.');
end
obj.plots = plots;
legend = {};
% Check if contained plots feature axis_labels
for plot_num=1:length(plots)
plot_axis_labels = get(plots{plot_num}, 'axis_labels');
if isempty(axis_labels) && ~isempty(plot_axis_labels)
if ~isempty(plot_axis_labels{1})
axis_labels{1} = plot_axis_labels{1};
end
if ~isempty(plot_axis_labels{2})
axis_labels{2} = plot_axis_labels{2};
end
end
plot_legend = get(plots{plot_num}, 'legend');
if ~ isempty(plot_legend)
legend = { legend{:}, plot_legend{:}};
else
legend = { legend{:}, ''};
end
end
if isempty(title_str)
title_str = get(plots{1}, 'title');
end
% always merge first plot's props
obj = class(obj, 'plot_superpose', ...
plot_abstract({}, axis_labels, title_str, ...
legend, '', ...
mergeStructs(props, get(plots{1}, 'props'))));
end