PlotComet_3D.m 8.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
function varargout = PlotComet_3D(x_data, y_data, z_data, varargin)

%function creates a moving comet plot in 3 dimensions using the specificed
%x, y, and z line data
%
%PlotComet_3D(x_data, y_data, z_data)
%
%Optional Input Arguements:
%cFigure, handle to the current figure or axes to create the plot in (will
%   add the line data to the plot regardless of whether hold is on
%
%Frequency, playback frequency, if not provided assumed to be 10 Hz
%
%blockSize, number of points in the comet tail, assumed to be 1/20 of
%   length(x_data) if not provided
%
%PlotComet_3D(x_data, y_data, z_data, 'cFigure',FigureHandle,...
%     'Frequency',freq, 'blockSize',num_points)
%
%tailFormat, a structured variable containing the fomrating requirements of
%   the tail (if different than the default red solid line)
%   ex: Tail = struct('LineWidth',2,'Color','g','LineStyle','*');
%   PlotComet_3D(x_data,y_data,z_data,'tailFormat',Tail);
%
%headFormat, a structued vairable containing the formating requirements of
%   the head (if different than the default blue circle)
%   ex: Head = struct('LineStyle','none','MarkerSize',8,'Marker','^','Color','k');
%   PlotComet_3D(x_data,y_data,z_data,'headFormat',head);
%   Note: 'LineSytle','none' is required since the head is plotted as a
%   single point!
%
%Optional Output Arguements
%hFigure = figure handle to the comet plot
%
%Example: Create a surface plot and construct a moving line plot through it
%with connected cyan stars and dashed line on a 50 points long tail
%and large green square for a head.
%
%%create some data for the surface
%[X, Y] = meshgrid(linspace(-1, 1, 25), linspace(-1, 1, 25));
%Z = X .* exp(-X.^2 - Y.^2);
%%open a new figure and plot the surface
%surf(X, Y, Z);
%fig = gcf;
%%create the line data
%t = -pi:pi/500:pi;
%x = sin(5*t);
%y = cos(3*t);
%z = t;
%%define the tail formated structure
%Tail = struct('LineStyle','--','Marker','*','Color','c',...
%   'LineWidth',2,'MarkerSize',4);
%%define the head formated structure
%Head = struct('LineStyle','none','Marker','s','Color','g','MarkerSize',10);
%
%%Invoke the comet plot with 50 Hz playback, and a tail length of 50 pts
%PlotComet_3D(x,y,z,'cFigure',fig,'blockSize',50,'Frequency',50,...
%   'headFormat',Head,'tailFormat',Tail);
%
%Nick Hansford
%09/26/2013

%initialize the inputs
freq = 10;
blockSize = floor(1/20*length(x_data));
tailFormat = struct('LineWidth',1,'Color','r','LineStyle','-');
headFormat = struct('LineStyle','none','Marker','o','MarkerSize',6,...
    'Color','b');
69 70 71
pointFormat = struct('LineStyle','none','Marker','o','MarkerSize',6,...
    'Color','g');
plotPoints = 0;
72

73
returnFrames = 0;
74

75 76
colorSwitch = 0;
moveTail = 0;
77 78 79 80 81


%parse out the inputs
argCount = nargin - 3;

82
for index = 1:2:argCount
83
    %         caseVar = varargin{i}
84
    switch varargin{index}
85
        case 'cFigure'
86
            cFigure = varargin{index+1};
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
            %get the original size:
            cAxes = get(cFigure,'CurrentAxes');
            xLim = get(cAxes,'XLim');
            yLim = get(cAxes,'YLim');
            zLim = get(cAxes,'ZLim');
            
            %resize if the new plot will exceed them
            if xLim(1) > min(x_data)
                xLim(1) = min(x_data);
            end
            
            if xLim(2) < max(x_data)
                xLim(2) = max(x_data);
            end
            
            if yLim(1) > min(y_data)
                yLim(1) = min(y_data);
            end
            
            if yLim(2) < max(y_data)
                yLim(2) = max(y_data);
            end
            
            if zLim(1) > min(z_data)
                zLim(1) = min(z_data);
            end
            
            if zLim(2) < max(z_data)
                zLim(2) = max(z_data);
            end
            
            axis([xLim, yLim, zLim]);
            
        case 'blockSize'
121
            blockSize = varargin{index+1};
122
        case 'Frequency'
123
            freq = varargin{index+1};
124 125
            
        case 'tailFormat'
126
            tailFormat = varargin{index+1};
127 128
            
        case 'headFormat'
129 130 131 132 133 134 135 136 137 138 139 140 141
            headFormat = varargin{index+1};
            
        case 'plotPoints'
            plotPoints = varargin{index+1};
        
        case 'returnFrames'
            returnFrames = varargin{index+1};
            
        case 'colorSwitch'
            colorSwitch = varargin{index+1};
            
        case 'moveTail'
            moveTail = varargin{index+1};
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    end
end
    
    
%make sure the figure exists, if not, create it
if ~exist('cFigure')
    cFigure = figure;
    view(3);
    axis([min(x_data), max(x_data),...
        min(y_data), max(y_data),...
        min(z_data), max(z_data)]);
end

    
%user can pass in current axes, if so, get the parent for the figure window
%and use that instead...should make this compatible with GUIs?
if strcmp(get(cFigure,'Type'),'axes')
    cFigure = get(cFigure,'Parent');
end

%activate the figure window
figure(cFigure);
cAxes = get(cFigure,'CurrentAxes');

oldNextPlot = get(cAxes,'NextPlot');
set(cAxes,'NextPlot','add');

pauseTime = 1./freq;

n_start = 1;
n_stop = 1;
173 174 175

frames = [];
deleteList = [];
176
%put on the starting point
177
deleteList{end+1} = plot3(x_data(n_start:n_stop),...
178 179
    y_data(n_start:n_stop),...
    z_data(n_start:n_stop),tailFormat);
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
deleteList{end+1} = plot3(x_data(n_stop), y_data(n_stop), z_data(n_stop),headFormat);

if returnFrames 
   frames{end+1} = getframe(gcf); 
end

% prepare the colormap
if colorSwitch
    colormap('jet');
    colorValues = colormap;
    colorValues = [colorValues;[0 0 0]];
    indexFactor = 3.882/1.335;
else
    indexFactor = 1;
end

196

197 198 199 200 201 202 203 204
if length(moveTail) > 1
    tailX_data = squeeze(moveTail(:,1,:));
    tailY_data = squeeze(moveTail(:,2,:));
    tailZ_data = squeeze(moveTail(:,3,:));
end

n_blocks = length(x_data)/blockSize;
i_blocks = 0;
205
%playback!
206
for n = 1:1:ceil(length(x_data)+length(x_data)/(n_blocks*indexFactor))
207
    a = tic;
208

209 210
       
    
211 212
    if n <= blockSize*(i_blocks + 1)
        n_start = blockSize*i_blocks + 1;
213 214
        n_stop = n;
    else
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
        i_blocks = i_blocks + 1;
        n_start = blockSize*i_blocks + 1;
        n_stop = n;
        
        deleteList = deleteList(2:end);
    end
    
    %delete the previous plot
    for index = 1:length(deleteList)
        delete(deleteList{index});
    end
    deleteList = [];
    
    
    if n > length(x_data)
%        n_start = 1;
       n_stop = length(x_data);
232 233 234
    end
    
    %new plot
235
    deleteList{end+1} = plot3(x_data(n_start:n_stop),...
236 237
        y_data(n_start:n_stop),...
        z_data(n_start:n_stop),tailFormat);
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    
    
    if plotPoints
        for index = 1:n_stop-1
           if colorSwitch
               colorIndex = round((n-(index-1))*indexFactor);
               if colorIndex >= length(colorValues)
                   colorIndex = length(colorValues);
               end
               pointColor = colorValues(colorIndex,:);
               pointFormat = struct('LineStyle','none','Marker','o','MarkerSize',6,'Color',pointColor);
           end
            if moveTail == 0
                deleteList{end+1} = plot3(x_data(index), y_data(index), z_data(index),pointFormat); 
            else
                if colorIndex ~= length(colorValues)
                    % point
                    deleteList{end+1} = plot3(tailX_data(index,colorIndex), tailY_data(index,colorIndex), tailZ_data(index,colorIndex),pointFormat); 
                end
                % tail
                deleteList{end+1} = plot3(tailX_data(index,1:colorIndex),...
                tailY_data(index,1:colorIndex),...
                tailZ_data(index,1:colorIndex),tailFormat);
            end
        end
        deleteList{end+1} = plot3(x_data(n_stop), y_data(n_stop), z_data(n_stop),headFormat); 
    else
        deleteList{end+1} = plot3(x_data(n_stop), y_data(n_stop), z_data(n_stop),headFormat);
    end
267 268
    drawnow;
    
269 270 271 272
    if returnFrames 
        frames{end+1} = getframe(gcf); 
    end
    
273 274 275 276 277
    %update playback refresh rate
    b = toc(a);
    pause(pauseTime-b);
end

278 279 280 281 282 283 284 285
if plotPoints
    plot3(x_data(n_stop), y_data(n_stop), z_data(n_stop),pointFormat);
    drawnow;
    if returnFrames 
        frames{end+1} = getframe(gcf); 
    end
end

286 287 288 289 290 291
set(cAxes,'NextPlot',oldNextPlot);
% fprintf('Finished\n');

if nargout == 1
    varargout{1} = cFigure;
end
292 293 294 295

if returnFrames 
   varargout{2} = frames;
end