Code covered by the BSD License  

Highlights from
Test and Measurement Seminar Demos

image thumbnail
from Test and Measurement Seminar Demos by Scott Hirsch
Source code for Test and Measurement Seminar Demos, including electronic throttle body case study.

linelabel(state,ind)
function linelabel(state,ind)
%linelabel       Identify a line by clicking on it.
%
% Application: Sometimes a legend just isn't good enough.
% With linelabel, clicking on a line labels it.  
%
%   LINELABEL turns on line labels for the lines in the current axis.
%   LINELABEL(handles) turns on line labels for the lines
%     specified in handles.  handles is a vector of handles
%     to line objects.  Lines are labeled by index (the first
%     line in handles is 1, the next is 2, ...)
%   LINELABEL(handles,[id_vector]) specifies numerical IDs for the lines.
%     id_vector must be the same length as handles
%   LINELABEL(handles,{id_cell}) specifies textual IDs for the lines
%     id_cell must be the same length as handles
%   LINELABEL(handles,'legend') Uses the labels specified in the legend
%   LINELABEL OFF turns line labeling off for the current figure
%
%	  Example: 
%       %NOTE: Interact with your plot after each call to linelabel
% 		s = sin(2*pi*linspace(0,1)')*(1:1:5);
% 		lh = plot(s);
% 		linelabel(lh)   %Number with index.
%        %Click on lines to label values.
%        %Click and drag to move label
%        %Right click to delete.
% 		linelabel off
%        %Existing line labels are locked in place; can't add more
% 		linelabel(lh,11:15)     %Provide your own numbers
% 		linelabel(lh,{'scott','writes','useful','MATLAB','utilities'})
%                               %Provide your own custom labels
% 		legend({'Ch1','Ch2','Ch3','Ch4','Ch5'})
% 		linelabel(lh,'legend')  %Automatically use the labels from the legend.
%
%  See also DATALABEL
%  
% This function is provided as an example only.  It has not been
% tested, and therefore, it is not officially supported by The
% MathWorks, Inc.

% Written by Scott Hirsch
% shirsch@mathworks.com
% Copyright 2002 - 2003 The MathWorks, Inc

%Option: if no input arguments, add indexed labels to the
% lines in the current axis.
if nargin==0
    state = flipud(findobj(gca,'Type','line'));
    %Find lines.  Flip, since findobj returns in reverse order.
end;


if ~isstr(state) % Set the WindowButtonDownFcn (turn on linelabel)
    %User call: specify handles to lines
    handles = state;
    if ~all(ishandle(handles))
        error('Input argument must be a vector of line handles');
    end;
    
    set(gcf,'WindowButtonDownFcn','linelabel down')
    set(gcf,'DoubleBuffer','on');       %eliminate flicker
    
    %Store identity to each line as appdata
    %There are four possibilities here:
    %1.  User doesn't specify anything (1 nargin).  Use 1:length(handles)
    %2.  User specifies a vector.  Use these.  arg2 = vector
    %3.  User specifies a cell array of strings.  arg2 = cell aray
    %3.  User says to use the labels in the legend.  arg2 = 'legend'
    %Regardless, end up with a cell array of strings.  Assign one 
    %  value to each handle, in order
    
    if nargin<2        %1.  User doesn't specify anything 
        ind = mat2cell(num2str((1:length(handles))'),ones(length(handles),1)); 
        
    elseif strcmp(ind,'legend')
        %Find the legend.
        %First, look for all legends on this figure
        
        current_axis = get(handles(1),'Parent');
        current_figure = get(current_axis,'Parent');
        
        legh = findobj(current_figure,'Tag','legend');
        if isempty(legh)
            error('Sorry, but you must have a legend to use this syntax.')
        end;
        
        %if we only found one legend, this is easy
        if length(legh)==1
            ud = get(legh,'UserData');  %Returns a struct
            ind = ud.lstrings;
        else
            ud = get(legh,'UserData');  %Returns a cell array of structs
            %Search through these to find the one belonging to our figure
            found=0;
            ii=0;
            while ~found
                ii=ii+1;
                if ud{ii}.PlotHandle == current_axis
                    found=1;
                    ind = ud{ii}.lstrings;
                end;
            end;
            
        end;

        %Ensure that the legend had one entry per handle
        if length(ind) ~= length(handles)
            error('Legend must have same number of entries as the input handle vector.');
        end;
        
        
    elseif ~iscell(ind)     %2.  User specifies a vector.
        %Check to be sure that index vector is same length as handles
        if length(ind) ~= length(handles)
            error('Index vector must be of same length as handle vector');
        end;
        
        ind = mat2cell(num2str(ind(:)),ones(length(handles),1));
        
    else                    %3.  User specifies a cell array of strings
        if length(ind) ~= length(handles)
            error('Index cell array must be of same length as handle vector');
        end;
    end;
    
    for ii=1:length(handles)
        setappdata(handles(ii),'Index',ind{ii});
    end;
    
elseif strcmp(state,'down') % Execute the WindowButtonDownFcn.  Add label
    htype = get(gco,'Type');
    tag = get(gco,'Tag');
    
    if strcmp(htype,'line')      %Line - Add text object
        
        %User-selected point
        cp = get(gca,'CurrentPoint');
        x = cp(1,1);       %first xy values
        y = cp(1,2);       %first xy values
        
        
        %Which line is this?
        lineno = getappdata(gco,'Index');
        th = text(x,y,lineno,'HorizontalAlignment','center');
        
        %Set background color of label.  MATLAB 6.5 or higher.
        v=ver('MATLAB');
        v=str2num(v.Version);
        if v>=6.5
            set(th,'BackgroundColor','y');
        end;
        
        
        mh = uicontextmenu('Tag','DeleteObject', ...
            'Callback','delete(gco);');
        
        set(th,'UIContextMenu',mh);
        
    elseif strcmp(htype,'text')     %Clicked on label - switch to moving
        set(gco,'EraseMode','xor')
        set(gcf,'WindowButtonMotionFcn','linelabel move', ...
            'WindowButtonUpFcn','linelabel up');
    end
    
elseif strcmp(state,'move') % Execute the WindowButtonMotionFcn. move label
    htype = get(gco,'Type');
    tag = get(gco,'Tag');
    if ~isempty(gco)
        
        th = gco;
        
        cp = get(gca,'CurrentPoint');
        pt = cp(1,[1 2]);
        
        x = cp(1,1);       %first xy values
        y = cp(1,2);       %first xy values
        
        set(th,'Position', [x y 0])
        
        drawnow
    end;
elseif strcmp(state,'up') % Execute the WindowButtonUpFcn
    htype = get(gco,'Type');
    tag = get(gco,'Tag');
    if strcmp(htype,'text')
        set(gco,'EraseMode','Normal')
        set(gcf,'WindowButtonMotionFcn','')
    end;
elseif strcmp(state,'off') % Unset the WindowButton...Fcns
    set(gcf,'WindowButtonDownFcn','','WindowButtonUpFcn','')
end

Contact us