Home > chronux_2_00 > spikesort > utility > uitools > linelabel.m

linelabel

PURPOSE ^

LINELABEL Labels plotted lines.

SYNOPSIS ^

function linelabel(vectors)

DESCRIPTION ^

LINELABEL         Labels plotted lines.
   LINELABEL(LIBRARY), allows the user to select points and labels each
   with the row number of its closest (Euclidean) match among the rows of
   the matrix LIBRARY.  When the mouse is clicked in the axis, the
   nearest point is selected and labeled.  The function stops when either
   the escape or the enter key is pressed.  For this usage, LIBRARY must
   by an (P x N) matrix, where P is the number of line objects in the
   current plot and N is the number of points per line.

   LINELABEL(QUERIES), where QUERIES is (M x N) for M less than the
   number of lines P in the current plot, skips the interactive step.  It
   instead searches through the lines on the current plot and, for each
   row of QUERIES, finds the closest (i.e., Euclidean) match.  This match
   is then labeled on the plot with the index of the corresponding row
   from QUERIES.

   LINELABEL('reset') deletes all text objects from the current axes and
   sets the 'LineWidth' of all lines to 1.  USE WITH CARE, since these
   effects are not restricted to those changes made by LINELABEL.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function linelabel(vectors)
0002 %LINELABEL         Labels plotted lines.
0003 %   LINELABEL(LIBRARY), allows the user to select points and labels each
0004 %   with the row number of its closest (Euclidean) match among the rows of
0005 %   the matrix LIBRARY.  When the mouse is clicked in the axis, the
0006 %   nearest point is selected and labeled.  The function stops when either
0007 %   the escape or the enter key is pressed.  For this usage, LIBRARY must
0008 %   by an (P x N) matrix, where P is the number of line objects in the
0009 %   current plot and N is the number of points per line.
0010 %
0011 %   LINELABEL(QUERIES), where QUERIES is (M x N) for M less than the
0012 %   number of lines P in the current plot, skips the interactive step.  It
0013 %   instead searches through the lines on the current plot and, for each
0014 %   row of QUERIES, finds the closest (i.e., Euclidean) match.  This match
0015 %   is then labeled on the plot with the index of the corresponding row
0016 %   from QUERIES.
0017 %
0018 %   LINELABEL('reset') deletes all text objects from the current axes and
0019 %   sets the 'LineWidth' of all lines to 1.  USE WITH CARE, since these
0020 %   effects are not restricted to those changes made by LINELABEL.
0021 
0022 %%%%%%%%%% SPECIAL CASE
0023 if(ischar(vectors) && strcmp(vectors, 'reset'))
0024     delete(findobj(gca, 'Type', 'Text'));
0025     set(findobj(gca, 'Type', 'Line'), 'LineWidth', 1);
0026     return;
0027 end
0028 
0029 %%%%%%%%%% ARGUMENT CHECKING
0030 lines = findobj(gca, 'Type', 'Line'); 
0031 if (isempty(lines)),  error('The plot does not contain any line objects.');  end
0032 
0033 ydatalines = get(lines, 'YData');
0034 xdatalines = get(lines, 'XData');
0035 datacolors = get(lines, 'Color');
0036 
0037 L = unique(cellfun('length', ydatalines));   % set of lengths of line objects
0038 if (length(L) > 1)  % all lines not same length?
0039     error('LINELABEL requires all line objects in the current plot to have the same length.');
0040 end
0041 P = size(ydatalines, 1);   [M,N] = size(vectors);
0042 xdatalines = cat(1, xdatalines{:});
0043 ydatalines = cat(1, ydatalines{:});
0044 datacolors = cat(1, datacolors{:});
0045 
0046 if (N ~= L)
0047     error('The input matrix must have the same number of columns as the lines in the current plot.');
0048 elseif (M > P)
0049     error('The input matrix can not have more rows than the number of lines in the current plot.');
0050 else
0051     X = unique(xdatalines, 'rows');
0052     if (size(X, 1) > 1)
0053         error('LINELABEL requires all line objects in the current plot to share the same XData');
0054     end
0055 end
0056 if ((xdatalines(1) ~= 1) || (~all(all(diff(xdatalines, 1, 2) == 1))))
0057     warning(['This function is currently designed to work with XData that ' ... 
0058             'starts at 1 and is evenly spaced.  Behavior with current plot may be unexpected.']);
0059 end
0060 
0061 
0062 xlim = get(gca, 'XLim');  ylim = get(gca, 'YLim');
0063 if (M == P)  %%%%%%%%%% INTERACTIVE CASE: label requested points with index of matches from 'vectors'
0064     while (true)
0065         [x,y,key] = ginput(1);
0066         if (isempty(x) || isequal(key, 27)),  break;   end
0067         nearestX = round(x);
0068         [howgood, index] = min(abs(ydatalines(:, nearestX) - y));
0069         if ((abs(((nearestX - x)./(xlim(2)-xlim(1)))) > 0.005) || ...  % too far from a valid x index
0070             (abs(((  howgood   )./(ylim(2)-ylim(1)))) > 0.005))        % or too far from a valid y index
0071             continue;
0072         end
0073         [dist,ind] = min(pairdist(vectors, ydatalines(index,:),'nosqrt'), [], 1);
0074         label = num2str(ind);
0075         text(x, y, label, 'FontWeight', 'bold', 'FontSize', 14, 'Color', getcolor(datacolors, index));
0076     end
0077 else         %%%%%%%%%% NONINTERACTIVE CASE: label closest matches to each row of 'vectors' with its index
0078     if (M > 100)
0079         areyousure = input(['Warning.  You are trying to label > 100 lines.\n' ...
0080                             'Enter y to continue or any other key to quit: '], 's');
0081         if (lower(areyousure(1)) ~= y)
0082             return;
0083         end
0084     end
0085     for test = 1:M
0086         match = sum((ydatalines - repmat(vectors(test,:), [size(ydatalines,1), 1])).^2, 2);
0087         [mn,index] = min(match);
0088         
0089         % Find the column that has the largest distance to the closest line (this'll
0090         % help if the line is an outlier for at least one coordinate).
0091         ydatacopy = ydatalines;
0092         ydatacopy(index,:) = Inf;        % don't consider self distance
0093         dist_to_lines = abs(ydatacopy - repmat(ydatalines(index,:),[P,1]));
0094         [junk,select] = max(min(dist_to_lines, [], 1), [], 2);    % largest dist to closest line
0095         text(X(select)*1.01, ydatalines(index,select)*0.99, num2str(test), ...  % this needs to be visible
0096                'FontWeight', 'bold', 'FontSize', 20, 'Color', getcolor(datacolors, index), ...
0097                'VerticalAlignment', 'baseline', 'HorizontalAlignment', 'right');
0098         set(lines(index), 'LineWidth', 3);
0099         uistack(lines(index), 'top');
0100     end
0101 end
0102 
0103 
0104 % Choose a color for the text label
0105 function color = getcolor(datacolors, index)
0106 if (size(unique(datacolors, 'rows'), 1) > 1) % if the lines aren't all the same color,
0107     color = brighten(datacolors(index,:), 0.5);
0108 else
0109     color = [1 1 1] - get(gca, 'Color');
0110 end

Generated on Fri 15-Aug-2008 11:35:42 by m2html © 2003