image thumbnail
from REFLINEXYZ by Jos (10584)
Plot 3D reference lines to the YZ-, XZ- and XY-planes

reflinexyz(x,y,z,varargin)
function hxy = reflinexyz(x,y,z,varargin)
% REFLINEXYZ - Plot 3D reference lines to the YZ-, XZ- and XY-planes
%   REFLINEXYZ(X,Y,Z) plots reference lines from the 3D points (X,Y,Z) to
%   the three cartesian planes (YZ, XZ, & XY planes). The lines are drawn
%   from the axes planes upto each point. X, Y and Z should have the same
%   number of elements. 
%
%   REFLINEXYZ(X,Y,Z,YZOFFSET, XZOFFSET, XYOFFSET) specifies the offset
%   from the three planes. If an offset is omitted (or empty), the
%   defaults are used, namely the lower limits of each axis. The offsets
%   can be scalars, specifying the same offset for each point, or vectors
%   with the same number of elements as the points, in order to specify the
%   offset for each point individually. 
%
%   The lines are plotted as a three graphics object. H = REFLINEXYZ(..) returns
%   the three graphics handles of the lines to the YZ, XZ and XY planes in H. 
%
%   REFLINEXYZ(..., 'Prop1','Val1','Prop2','Val2', ...) uses the properties
%   and values specified for color, linestyle, etc. Execute GET(H), where H is
%   a line handle, to see a list of line object properties and their current values.
%   Execute SET(H) to see a list of line object properties and legal property values.
%   REFLINEXYZ uses the current axes, if any. Lines outside the plot area
%   are plotted but not shown.
%
%   Example:
%     % create and plot some data
%       N = 50 ; i=0:N ;
%       x = (i/N) * 2 * pi ;
%       y = exp(i/N) .* sin(3*x) ;
%       z = (2*i/N).^2 ;
%       plot3(x,y,z,'bo-') ;
%       xlabel('X-axis') ; ylabel('Y-axis') ; zlabel('Z-axis') ; grid on ;
%     % add specific reference lines
%       i0 = [10 20] ; % indices of points
%       h = reflinexyz(x(i0),y(i0),z(i0),'color','r','linestyle','-','linewidth',3,'marker','.') ;
%       title ('Reference lines to 2 points') ;
%       disp('Press a key') ; pause ; 
%     % make a projection to xy-plane
%       hold on ; plot3(x,y,zeros(size(x)),'k.-') ; hold off ;
%       h = reflinexyz(x,y,z,'color','k','linestyle','-') ; 
%       delete(h([1 2])) ; % delete the yz and xz projections
%       title ('Projection to XY plane') ;
%
%   See also STEM, PLOT3, REFLINE, GRID, AXES
%   and GRIDXY and REFLINEXY (on the FEX)

% for Matlab R13
% version 1.2 (okt 2007)
% (c) Jos van der Geest
% email: jos@jasen.nl

% History:
% 1.0 (okt 2007) - created
% 1.1 (okt 2007) - small code revisions (variable names) and added comments
% 1.2 (okt 2007) - removed spelling and grammar errors

error(nargchk(3,Inf,nargin)) ;

% get the axes to plot in
hca=get(get(0,'currentfigure'),'currentaxes');
if isempty(hca),
    warning('No current axes found') ;
    return ;
end

% check the arguments
if ~isnumeric(x) || ~isnumeric(y) || ~isnumeric(z),
    error('Three numeric arguments expected') ;
end

N = numel(x) ;

if ~isequal(N,numel(y), numel(z)),
    error('X, Y and Z should have the same number of elements') ;
end

% assume that the reference are to be draw from the "bottom" of the planes
xyz0(1:3) = {[]} ; 



if nargin==3,
    va = [] ;
else
    % Parse the first 3 arguments arguments
    va = varargin ;
    for i=1:3,
        tmp = va{1} ;        
        if isnumeric(tmp),
            % numeric argument specifies offset
            if ~isempty(tmp),                
                if numel(tmp)==1,
                    xyz0{i} = repmat(tmp,N,1) ;
                elseif numel(tmp) ~= N,
                    error('Offsets should have the same number of elements as the 3D points (or be scalars).') ;
                else
                    xyz0{i} = tmp(:) ;
                end               
                va = va(2:end) ;
            end
        elseif ischar(tmp),
            % a char-array wil specify line properties, so break
            break ; 
        else
            error('Parameter %d is invalid',i+3) ;
        end
    end       
end

% minimum check for property-value pairs
if mod(size(va),2) == 1,
    error('Property-Value have to be pairs') ;
end

% get the current limits of the axis
% also used for limit restoration later on
xyzlim{1} = get(hca,'xlim') ;
xyzlim{2} = get(hca,'ylim') ;
xyzlim{3} = get(hca,'zlim') ;

% create offsets for the three planes
for i=1:3,
    if isempty(xyz0{i}),
        tmp = xyzlim{i} ;
        xyz0{i} = repmat(tmp(1),1,N) ;
    end
    tmp = xyz0{i} ;
    xyz0{i} = tmp(:).' ; % column vector
end

if N,   
    nanfill = repmat(nan,1,N) ;
    
    % build the lines
    xx = repmat(x(:).',3,1) ; xx = xx(:) ;
    yy = repmat(y(:).',3,1) ; yy = yy(:) ;
    zz = repmat(z(:).',3,1) ; zz = zz(:) ;
    xxnan = [xyz0{1} ; x(:).' ; nanfill] ;
    yynan = [xyz0{2} ; y(:).' ; nanfill] ;
    zznan = [xyz0{3} ; z(:).' ; nanfill] ;
        
    % add the line to the current axes
    np = get(hca,'nextplot') ;
    set(hca,'nextplot','add') ;
    hxy(1) = line('xdata',xxnan(:),'ydata',yy,'zdata',zz,'linestyle',':','color','k') ; % draw lines to yz-plane
    hxy(2) = line('xdata',xx,'ydata',yynan(:),'zdata',zz,'linestyle',':','color','k') ; % draw lines to xz plane
    hxy(3) = line('xdata',xx,'ydata',yy,'zdata',zznan(:),'linestyle',':','color','k') ; % draw lines to xy plane
        
    uistack(hxy,'bottom') ; % push lines to the bottom of the graph
    
    set(hca,'nextplot',np) ;    % reset the nextplot state
    set(hca,'xlim',xyzlim{1},'ylim',xyzlim{2},'zlim',xyzlim{3}) ; % reset the limits
    
    if ~isempty(va),
        try
            set(hxy,va{:}) ; % set line properties        
        catch
            % invalid arguments, modify error message
            delete(hxy) ;
            msg = lasterror ;
            error(msg.message(21:end)) ;    
        end
    end
else
    hxy = [] ;
end

% if requested return handles
if ~nargout,     
    clear hxy ;
end

Contact us at files@mathworks.com