![]() |
RTXI 1.3
|
00001 function fig = rtxiplot(varargin) 00002 % fig = rtxiplot(varargin) 00003 % 00004 % INPUTS: varargin must contain a minimum of three arguments and can use 4 00005 % optional arguments in the following order: 00006 % 00007 % optional: figure handle 00008 % captions for listbox (cell) 00009 % parameters (a struct: entries are listed in the parameter panel 00010 % of the GUI) 00011 % meta (a struct: metadata to pass through to the figure) 00012 % required: x data 00013 % y data 00014 % plot style ('k-') 00015 % 00016 % OUTPUTS: 00017 % fig - returns the figure handle that was used 00018 % 00019 % Used by rtxibrowse.m to create the GUI and plot all channels from a 00020 % single trial extracted from an RTXI HDF5 file. The "Prev" and "Next" 00021 % buttons are only applicable in this scenario since it uses metadata such 00022 % as the HDF5 file name to browse through all the trials. 00023 % 00024 % AUTHOR: Risa Lin 00025 % DATE: 10/31/2010 00026 % 00027 % MODIFIED: 00028 % 9/27/2011 - supports unmatlabized RTXI files and strings 00029 00030 k = 1; % parameter counter 00031 if k <= numel(varargin) && isscalar(varargin{k}) && ishandle(varargin{k}) % re-use existing figure 00032 fig = varargin{k}; 00033 tag = get(fig, 'Tag'); 00034 assert(~isempty(tag) && strcmp(tag, '__rtxiplot__'), ... % verify figure tag 00035 'rtxiplot:ArgumentTypeMismatch', 'An rtxiplot figure is expected.'); 00036 k = k + 1; 00037 elseif k <= numel(varargin) && ischar(varargin{k}) && strcmp('new', varargin{k}) % force creation of new figure 00038 fig = rtxiplot_figure(); 00039 k = k + 1; 00040 else 00041 curfig = get(0,'CurrentFigure'); 00042 h = findobj('Type', 'figure', 'Tag', '__rtxiplot__'); 00043 if isempty(h) % create new figure if no rtxiplot figure exists yet 00044 fig = rtxiplot_figure(); 00045 setappdata(fig,'reset',0); % do not reset listbox contents 00046 elseif isscalar(h) % a single rtxiplot figure exists 00047 if ~isempty(curfig) && h == curfig % currently active figure is an rtxiplot figure 00048 fig = curfig; 00049 else 00050 fig = h; 00051 figure(fig); % currently active figure is not an rtxiplot figure, activate the only rtxiplot figure 00052 end 00053 else % multiple rtxiplot figures exist 00054 if ~isempty(curfig) 00055 ix = find(h == curfig); % ix is either empty or a scalar 00056 else 00057 ix = []; 00058 end 00059 if isscalar(ix) % current figure is an rtxiplot figure 00060 fig = curfig; 00061 else % isempty(ix) 00062 fig = h(1); % use rtxiplot figure topmost in stacking order 00063 figure(fig); 00064 warning('rtxiplot:InvalidOperation', ... 00065 'Currently active figure is not an rtxiplot figure, the topmost rtxiplot figure has been activated.'); 00066 end 00067 end 00068 end 00069 00070 if k <= numel(varargin) && ischar(varargin{k}) % get channel names as captions for listbox 00071 caption = varargin{k}; 00072 k = k + 1; 00073 else % use default caption 00074 caption = []; 00075 end 00076 00077 if k <= numel(varargin) && isstruct(varargin{k}) % get parameters 00078 parameters = varargin{k}; 00079 k = k + 1; 00080 else % use default caption 00081 parameters = []; 00082 end 00083 00084 if k <= numel(varargin) && isstruct(varargin{k}) % get meta data 00085 meta = varargin{k}; 00086 k = k + 1; 00087 else % use default caption 00088 meta = []; 00089 end 00090 setappdata(fig,'meta',meta) 00091 00092 00093 if k > numel(varargin) % nothing to plot 00094 if ~isempty(caption) 00095 warning('rtxiplot:InvalidOperation', ... 00096 'A caption is specified but no data to plot has been passed.'); 00097 return; 00098 end 00099 return; 00100 end 00101 varargin = varargin(k:end); % drop preprocessed arguments 00102 00103 ppanel = findobj(fig,'Tag','parameterpanel'); 00104 uicontrol(ppanel, ... 00105 'Style','text', ... 00106 'Units','normalized', ... 00107 'Position', [0 .9 1 0.1], ... 00108 'String','INITIAL PARAMETERS'); 00109 00110 if (ischar(parameters.values{1})) % is string 00111 pstr = ['[{''',parameters.modelName{1},' : ',parameters.parameterName{1},' : ',parameters.values{1}]; 00112 else % get the second value, the first is the timestamp 00113 pstr = ['[{''',parameters.modelName{1},' : ',parameters.parameterName{1},' : ',num2str(parameters.values{1}{1,2})]; 00114 end 00115 00116 %pstr = ['[{''',parameters.modelName{1},' : ',parameters.parameterName{1},' : ',num2str(parameters.values{1}{1,2})]; 00117 if size(parameters.values{1},1)>1 00118 pstr=[pstr,'*''}']; 00119 else 00120 pstr=[pstr,'''}']; 00121 end 00122 for p=2:length(parameters.parameterName) 00123 if (ischar(parameters.values{p})) % get string 00124 pstr = [pstr,';{''',strrep(parameters.modelName{p},'''',''''''),' : ',strrep(parameters.parameterName{p},'''',''''''),' : ',parameters.values{p}]; 00125 else % get the second value, the first is the timestamp 00126 pstr = [pstr,';{''',strrep(parameters.modelName{p},'''',''''''),' : ',strrep(parameters.parameterName{p},'''',''''''),' : ',num2str(parameters.values{p}{1,2})]; 00127 end 00128 00129 %pstr = [pstr,';{''',strrep(parameters.modelName{p},'''',''''''),' : ',strrep(parameters.parameterName{p},'''',''''''),' : ',num2str(parameters.values{p}{1,2})]; 00130 if size(parameters.values{p},1)>1 00131 pstr=[pstr,'*''}']; 00132 else 00133 pstr=[pstr,'''}']; 00134 end 00135 end 00136 pstr = [pstr,']']; 00137 00138 eval(['uicontrol(ppanel,''Style'',''text'',''Units'',''normalized'',''FontSize'',9,''Position'', [.03 0 0.95 0.95],''HorizontalAlignment'',''Left'',''String'',',pstr,');']); 00139 00140 listbox1 = findobj(fig, 'Type', 'uicontrol', 'Tag', 'listbox1'); 00141 string = get(listbox1, 'String'); % cell array of all the item strings 00142 if getappdata(fig,'reset')==1; 00143 userdata = {}; 00144 string = {}; 00145 set(listbox1,'Value',1); 00146 else 00147 userdata = get(listbox1, 'UserData'); 00148 end 00149 if numel(string) > 100 00150 warning('rtxiplot:InvalidOperation', 'There are too many plots, new plot has not been added.'); 00151 return; 00152 end 00153 if numel(string) == 1 && strcmp(string, '[empty]') % there is only the placeholder item in the list 00154 string = {}; % clear placeholder item 00155 userdata = {}; 00156 end 00157 userdata{numel(userdata)+1} = varargin; % add arguments to plot function 00158 if isempty(caption) 00159 caption = sprintf('Plot %d', numel(userdata)); 00160 end 00161 string{numel(string)+1} = caption; % add caption used in list box 00162 set(listbox1, ... 00163 'String', string, ... 00164 'TooltipString', 'Double-click item (or hit ENTER) to plot in new figure window.', ... 00165 'UserData', userdata); 00166 if numel(string) <= 1 00167 rtxiplot_onselectionchange(listbox1); % show first selection by default 00168 end 00169 00170 listbox2 = findobj(fig, 'Type', 'uicontrol', 'Tag', 'listbox2'); 00171 string = get(listbox2, 'String'); 00172 if getappdata(fig,'reset')==1; 00173 userdata = {}; 00174 string = {}; 00175 set(listbox2,'Value',1); 00176 else 00177 userdata = get(listbox2, 'UserData'); 00178 end 00179 if numel(string) > 100 00180 warning('rtxiplot:InvalidOperation', 'There are too many plots, new plot has not been added.'); 00181 return; 00182 end 00183 if numel(string) == 1 && strcmp(string, '[empty]') % there is only the placeholder item in the list 00184 string = {}; % clear placeholder item 00185 userdata = {}; 00186 end 00187 userdata{numel(userdata)+1} = varargin; % add arguments to plot function 00188 if isempty(caption) 00189 caption = sprintf('Plot %d', numel(userdata)); 00190 end 00191 string{numel(string)+1} = caption; % add caption used in list box 00192 set(listbox2, ... 00193 'String', string, ... 00194 'TooltipString', 'Double-click item (or hit ENTER) to plot in new figure window.', ... 00195 'UserData', userdata); 00196 if numel(string) <= 1 00197 rtxiplot_onselectionchange(listbox2); % show first selection by default 00198 end 00199 setappdata(fig,'reset',0); 00200 00201 function fig = rtxiplot_figure() 00202 % Creates a new rtxiplot figure. 00203 00204 fig = figure( ... 00205 'Tag', '__rtxiplot__'); % ensures that all necessary controls are present 00206 00207 try 00208 % try to use uisplitter if available 00209 00210 [leftpanel,rightpanel] = uisplitpane(fig,'DividerWidth', 2,'DividerLocation', 0.25,'Orientation','hor'); 00211 [boxpanel,plotpanel] = uisplitpane(rightpanel,'DividerWidth',2,'DividerLocation',0.25,'Orientation','hor'); 00212 [topbox,bottombox] = uisplitpane(boxpanel,'DividerWidth',2,'DividerLocation',0.5,'Orientation','vert'); 00213 [topplot,bottomplot] = uisplitpane(plotpanel, 'DividerWidth',2,'Orientation','vert'); 00214 [bttnpanel,ppanel] = uisplitpane(leftpanel,'DividerWidth',2,'DividerLocation',0.1,'Orientation','vert'); 00215 set(leftpanel,'Tag','leftpanel'); 00216 set(ppanel,'Tag','parameterpanel'); 00217 set(bttnpanel,'Tag','buttonpanel'); 00218 set(rightpanel,'Tag','rightpanel'); 00219 set(boxpanel,'Tag','leftpanel'); 00220 set(plotpanel,'Tag','plotpanel'); 00221 set(topbox,'Tag','topbox'); 00222 set(bottombox,'tag','bottombox'); 00223 set(bottomplot,'Tag','bottomplot'); 00224 set(topplot,'Tag','topplot'); 00225 catch 00226 msgbox('Get uisplitter!'); 00227 end 00228 00229 prev_button = uicontrol(bttnpanel,'Style','pushbutton',... 00230 'Units','normalized',... 00231 'String','Prev',... 00232 'Position',[0.03 0.15 0.4 0.8], ... 00233 'Callback', @prev_button_callback); 00234 00235 next_button = uicontrol(bttnpanel,'Style','pushbutton',... 00236 'Units','normalized',... 00237 'String','Next',... 00238 'Position',[0.5 0.15 0.4 0.8], ... 00239 'Callback', @next_button_callback); 00240 00241 listbox1 = uicontrol(topbox, ... % allows selection of data to plot 00242 'Style', 'listbox', ... 00243 'Units', 'normalized', ... 00244 'Position', [.03 0.03 0.95 .95], ... 00245 'String', {'[empty]'}, ... % placeholder item 00246 'Tag', 'listbox1', ... 00247 'Callback', @rtxiplot_onselectionchange); 00248 00249 listbox2 = uicontrol(bottombox, ... % allows selection of data to plot 00250 'Style', 'listbox', ... 00251 'Units', 'normalized', ... 00252 'Position', [0.03 0.03 0.95 .95], ... 00253 'String', {'[empty]'}, ... % placeholder item 00254 'Tag', 'listbox2', ... 00255 'Callback', @rtxiplot_onselectionchange); 00256 00257 axes('Parent', topplot); 00258 axes('Parent', bottomplot); 00259 set(listbox2, 'UserData', {{}}); % no plot arguments belong to placeholder item 00260 set(listbox1, 'UserData', {{}}); % no plot arguments belong to placeholder item 00261 00262 00263 function rtxiplot_plot(ax, varargin) 00264 % Plots data in an rtxiplot figure with the specified plot arguments. 00265 % 00266 % Input arguments: 00267 % ax: 00268 % an axes handle graphics object 00269 % varargin (optional): 00270 % parameters to pass to the plot function 00271 00272 if nargin >= 2 00273 try 00274 plot(ax, varargin{:}); 00275 xlabel(ax,'time (s)'); 00276 catch me 00277 disp('plot function produces an error when passed parameters:'); 00278 args = varargin(:); 00279 disp(args); 00280 rtxiplot_error(ax); 00281 rethrow(me); 00282 end 00283 else % nothing to plot 00284 rtxiplot_hideaxes(ax); 00285 end 00286 00287 function prev_button_callback(src,eventdata) 00288 fig = ancestor(src, 'figure'); 00289 meta = getappdata(fig,'meta'); 00290 if meta.trialNum-1 >= 1 00291 trial = getTrial(meta.fname,meta.trialNum-1); 00292 meta.trialNum = meta.trialNum - 1; 00293 setappdata(fig,'meta',meta); 00294 setappdata(fig,'reset',1); % clear listbox contents 00295 rtxibrowse(fig,meta.fname,meta.trialNum); 00296 else 00297 msgbox('This is the first trial in the file!'); 00298 00299 end 00300 00301 function next_button_callback(src,eventdata) 00302 fig = ancestor(src, 'figure'); 00303 meta = getappdata(fig,'meta'); 00304 if meta.trialNum+1 <= meta.numTrials 00305 trial = getTrial(meta.fname,meta.trialNum+1); 00306 meta.trialNum = meta.trialNum + 1; 00307 setappdata(fig,'meta',meta); 00308 setappdata(fig,'reset',1); % clear listbox contents 00309 rtxibrowse(fig,meta.fname,meta.trialNum); 00310 else 00311 msgbox('This is the last trial in the file!'); 00312 00313 end 00314 00315 00316 function rtxiplot_onselectionchange(listbox, event) %#ok<INUSD> 00317 % Fired when the selected list item changes. 00318 00319 fig = ancestor(listbox, 'figure'); 00320 index = get(listbox, 'Value'); 00321 tag = get(listbox,'Tag'); 00322 if isempty(index) 00323 ax = findobj(fig, 'Type', 'axes'); 00324 rtxiplot_hideaxes(ax); 00325 return; 00326 end 00327 00328 userdata = get(listbox, 'UserData'); 00329 args = userdata{index}; 00330 allaxes = findobj(fig,'Type','axes'); 00331 panels = findobj(fig,'Type','uipanel'); 00332 for i=length(panels):-1:1 00333 if strcmp(get(panels(i),'Tag'),'topplot') 00334 topaxesparent = panels(i); 00335 elseif strcmp(get(panels(i),'Tag'),'bottomplot') 00336 bottomaxesparent = panels(i); 00337 end 00338 end 00339 00340 switch get(fig, 'SelectionType') 00341 case 'open' %% when you double-click, copies plot to new figure 00342 string = get(listbox, 'String'); 00343 caption = string{index}; 00344 if ~isempty(caption) 00345 meta = getappdata(fig,'meta'); 00346 newfigname = [meta.fname,' | Trial ',num2str(meta.trialNum),'/',num2str(meta.numTrials),' | ',caption]; 00347 newfig = figure('Name', newfigname); % open new figure window 00348 else 00349 newfig = figure; 00350 end 00351 ax = axes('Parent', newfig); 00352 00353 otherwise % pass clean axes to user-defined function 00354 if strcmp(tag,'listbox1') % find axes handle for top plot 00355 if get(allaxes(1),'Parent')==topaxesparent 00356 ax = allaxes(1); 00357 elseif get(allaxes(2),'Parent')==topaxesparent 00358 ax = allaxes(2); 00359 end 00360 elseif strcmp(tag,'listbox2') % find axes handle for bottom plot 00361 if get(allaxes(1),'Parent')==bottomaxesparent 00362 ax = allaxes(1); 00363 elseif get(allaxes(2),'Parent')==bottomaxesparent 00364 ax = allaxes(2); 00365 end 00366 end 00367 end 00368 00369 if numel(args) > 0 && isa(args{1}, 'function_handle') 00370 try 00371 fun = args{1}; % unwrap function handle from cell array 00372 fun(ax, args{2:end}); % call user-defined function passing axes as argument 00373 catch me 00374 rtxiplot_error(ax); 00375 rethrow(me); 00376 end 00377 else 00378 rtxiplot_plot(ax, args{:}); 00379 end 00380 set(ax, 'Visible', 'on'); 00381 00382 function rtxiplot_hideaxes(ax) 00383 00384 cla(ax, 'reset'); 00385 set(ax, 'Visible', 'off'); 00386 00387 function rtxiplot_error(ax) 00388 00389 rtxiplot_hideaxes(ax); 00390 msgbox('Error while plotting data to axes, see console for details.', ... 00391 'Plot error', 'error');