Skip to content
Snippets Groups Projects
gtPlotMultiScatter3DMatrix.m 7.43 KiB
Newer Older
function [h_obj, data_obj] = gtPlotMultiScatter3DMatrix(data, varargin)
% GTPLOTMULTISCATTER3DMATRIX  Plots matrices in the same plot
%     [h_obj, data_obj] = gtPlotMultiScatter3DMatrix(data, varargin)
%     --------------------------------------------------------------
%     INPUT:
%       data          = <cell array>   UVW data to plot for each dataset <cell> (Nx3) 
%
%     OPTIONAL INPUT (parse by pairs as varargin):
%       ids           = <cell array>   indexes to consider for each dataset <double> {all}
%       markers       = <cell array>   marker for each dataset <string> (1xP) {'xr','.b','og','xk','sm','db'}
%       cmap          = <cell array>   cmap for each point for each dataset <double> (Nx3) {[]}
%       labels        = <cell array>   entry in the legend for each dataset <string> (1xP) {[]}
%
%       leg_show      = <logical>      display or not the legend {true} | false
%       leg_pos       = <string>       legend position {[0.75 0.8 0.2 0.05]}
%       leg_color     = <double>       legend bkg RGB color {[1 1 1]}
%       leg_textcolor = <double>       legend text RGB color {[0 0 0]}
%       leg_replace   = <logical>      replace existing legend position and colors {true}
%
%       view          = <double>       axes view property {[0 90]}
%       xlim          = <double>       x axis limits {[]}
%       ylim          = <double>       y axis limits {[]}
%       zlim          = <double>       z axis limits {[]}
%       axes_labels   = <cell array>   labels for axes X Y and Z respectively <string> {'X','Y','Z'}
%       axes_pos      = <double>       axes position {[0.05 0.1 0.75 0.8]}
%       axes_tag      = <string>       axes tag {''}
%       axes_replace  = <logical>      reset position, in normalized units and tag {true}
%       axes_title    = <string>       axes title {''}
%       rotate3d      = <logical>      enables axes rotation in 3D {false}
%
%       fig_pos       = <double>       figure position {[0.2 0.1 0.65 0.7]}
%       fig_replace   = <logical>      reset position,in normalized units {true}
%
%       h_figure      = <handle>       figure handle {[]}
%       h_axes        = <handle>       axes handle {[]}
%       h_points      = <handle>       scatter points handle {[]}
%       h_legend      = <handle>       legend handle {[]}
%
%       debug         = <logical>      display comments {true}
%
%     OUTPUT:
%       h_obj         = <handle>       objects handles (1xP)
%       data_obj      = <handle>       data plotted in the figure <double> (Mx3)
%
%
%     Version 003 27-09-2013 by LNervo


% cell arrays
app.ids     = arrayfun(@(num) 1:size(data{num},1), 1:length(data), 'UniformOutput', false);
app.markers = {'s','o','o','x','.','d'};
app.cmap    = {'r','b','g','k','m','b'};
app.labels  = cell(size(data));
% legend
app.leg_show      = true;
app.leg_pos       = [0.75 0.8 0.2 0.05];
app.leg_color     = [1 1 1];
app.leg_textcolor = [0 0 0];
app.leg_replace   = true;
% axes
app.view         = [0 90];
app.xlim         = [];
app.ylim         = [];
app.zlim         = [];
app.axes_labels  = {'X','Y','Z'};
app.axes_pos     = [0.05 0.1 0.75 0.8];
app.axes_tag     = 'axes';
app.axes_replace = true;
app.axes_title   = '';
app.rotate3d     = false;
% figure
app.fig_pos     = [0.2 0.1 0.65 0.7];
app.fig_replace = true;
% handles
app.h_figure = [];
app.h_axes   = [];
app.h_points = [];
app.h_legend = [];
% debug
app.debug = true;
app.filled = true;

app = parse_pv_pairs(app, varargin);

% pick up only the right number of different markers
app.markers = app.markers(1:numel(data));
app.data    = [];

% create the figure
if isempty(app.h_figure)
    f1 = figure();
    app.h_figure = f1;
else
    f1 = app.h_figure;
    app.fig_replace = false;
end
figure(f1)
if (app.fig_replace)
    set(f1,'Units','normalized','Position',app.fig_pos)
end

% create the axes
if ~isempty(app.h_axes)
    axes(app.h_axes)
else
    app.h_axes = gca;
    app.axes_replace = false;
end
if (app.axes_replace)
    set(app.h_axes,'Position',app.axes_pos,'Units','normalized','Tag',app.axes_tag);
end
hold(app.h_axes, 'on');

% drawing
h_p = cell(numel(data),1);
for ii=1:numel(data)
    % get values
    tmp_var = data{ii};
    % get ids
    tmp_var = tmp_var(app.ids{ii},:);
    if ~isempty(tmp_var)
        if ~isempty(app.cmap{ii}) && isnumeric(app.cmap{ii})
            cmap = app.cmap{ii};
            if all(cmap(1,:)==[0 0 0]) && size(cmap,1) > 1
                cmap = cmap(2:end,:);
            end
            if size(cmap,1) ~= length(tmp_var)
                cmap  = repmat(cmap,length(tmp_var),1);
            end
            cmap = cmap(app.ids{ii},:);
           
            app.cmap{ii} = cmap;
            if (app.filled)
                h_p{ii} = scatter3(tmp_var(:,1), tmp_var(:,2), tmp_var(:,3), 'fill', app.markers{ii}, 'CData', cmap);
            else
                h_p{ii} = scatter3(tmp_var(:,1), tmp_var(:,2), tmp_var(:,3), app.markers{ii}, 'CData', cmap);
            end
        else
            if (app.filled)
                h_p{ii} = scatter3(tmp_var(:,1), tmp_var(:,2), tmp_var(:,3), 'fill', app.markers{ii});
            else
                h_p{ii} = scatter3(tmp_var(:,1), tmp_var(:,2), tmp_var(:,3), app.markers{ii});
            end
        end
        % children of handle are stacked in the reverse order : from the
        % last to the first
        h_child = get(h_p{ii},'Children');
        h_child = sort(h_child, 'ascend');
        for jj = 1 : length(h_child)
            sfSetInfo(h_child(jj), tmp_var(jj,:));
            set(h_child(jj), 'Tag', sprintf('data_%d_%d',ii,jj))
        end
    end
    app.data{ii} = tmp_var;
end % end for ii
app.h_points = h_p;

% avoid warning Painter's mode
set(gcf, 'Renderer', 'zbuffer');

% legend
leg = findobj(app.h_figure, 'Tag', 'legend');
if ~isempty(leg)
    leg_data          = get(leg, 'UserData');
    leg_data.lstrings = [leg_data.lstrings; app.labels];
    leg_data.handles  = [leg_data.handles; [app.h_points{:}]];
    
    app.leg_pos       = get(leg, 'Position');
    app.leg_color     = get(leg, 'Color');
    app.leg_textcolor = get(leg, 'TextColor');
    if (app.leg_replace)
        set(leg, 'UserData', leg_data)
    end
end
if (app.leg_show)
    if isempty(leg)
        leg = legend(leg,'Parent',app.h_figure,'String',app.labels',...
          'Position',app.leg_pos,'Color',app.leg_color,'TextColor',app.leg_textcolor);
    end
    app.h_legend = leg;
end

% axes options
axis(app.h_axes,'equal');
xlabel(app.axes_labels{1});
ylabel(app.axes_labels{2});
zlabel(app.axes_labels{3});

if ~isempty(app.xlim)
    set(app.h_axes, 'XLim', app.xlim)
end
if ~isempty(app.ylim)
    set(app.h_axes, 'YLim', app.ylim)
end
if ~isempty(app.zlim)
    set(app.h_axes, 'ZLim', app.zlim)
end
box(app.h_axes, 'on');
grid(app.h_axes, 'on');
if ~isempty(app.axes_title)
    set(get(app.h_axes, 'Title'),'String',app.axes_title);
    set(f1,'Name',strrep(app.axes_title,'\_','_'))
end
app.h_figure = f1;
if (app.rotate3d)
    % 3D rotation ON
    h=rotate3d(app.h_figure);
    set(h,'Enable','on','RotateStyle','Box');
end
view(app.view);

% save application data
set(app.h_figure,'UserData',app);
% show options
print_structure(app,'options',false,app.debug)

if nargout > 0
    h_obj = app.h_points;
    if nargout > 1
        data_obj = app;
    end
end

end % end of function

% sub-functions

function sfSetInfo(hObj, xyz)

    text = sprintf('%%s: %5.1f  %%s: %5.1f  %%s: %5.1f  %%s: %s  %%s',xyz(1),xyz(2),xyz(3),'%5.1f') ;

    set(hObj, 'UserData', text)

end % end function sfSetUVWinfo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%