RTXI 1.3
hdf/RTXIh5_MATLAB/rtxiplot.m
Go to the documentation of this file.
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');
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines