Code covered by the BSD License  

Highlights from
clickableLegend

image thumbnail
from clickableLegend by Ameya Deoras
A legend with clickable strings that let you hide and show objects in a plot.

clickableLegend(varargin)
function varargout = clickableLegend(varargin)
% clickableLegend is a wrapper around the LEGEND function that provides the
% added functionality to turn on and off (hide or show) a set of graphics
% objects (lines or patches) by clicking on an associated text label in the legend. Its usage is
% the same as the <a href="matlab: help legend">LEGEND</a> function with additional optional parameters. For
% further information please see the LEGEND documentation.
%
% ADDITIONAL ARGUMENTS specific to clickableLegend:
% These are passed in as parameter-value pairs
%
% * groups: A vector specifying the group membership for every line object.
%   The grouping parameter lets you have a group of lines represented and
%   controlled by one entry in the legend. This can be useful if you would
%   like to show or hide a group of lines by clicking on one legend entry.
%   CONSIDERATIONS:
%   # The number of unique entries in the group vector must match the
%     number of strings in the legend
%   # When passing a vector of line/patch handles as the first input
%     argument, the vector should contain all lines/patches whose group
%     membership is included in the group vector. ie. the length of the
%     vector of handles must match that of the length of the group vector.
% 
% * displayedLines: A vector of indices corresponding to the lines or groups that
%   should be displayed initially. This option is useful if there are too
%   many lines in the figure and you are only interested in looking at a
%   few at first.
%   Example: clickableLegend(..., 'displayedLines', [4 5 6])
%
% Notes: 
% 1. If you save the figure and re-load it, the toggling functionality
% is not automatically re-enabled. To restore it, simply call clickableLegend
% with no arguments.
%
% 2. To prevent the axis from automatically scaling every time a line is
% turned on and off, issue the command: axis manual
%
% Example 1:
% z = peaks(100);
% plot(z(:,26:5:50))
% grid on;
% axis manual;
% clickableLegend({'Line1','Line2','Line3','Line4','Line5'}, 'Location', 'NorthWest');
%
% Example 2:
% f = plot([1:10;1:2:20]','x'); hold on;
% g = plot(sin([1:10;1:2:20]'),'r-');
% h = plot(11:20,rand(5,10)*5,'b:');
% clickableLegend([f;g;h], {'Line1','Line2','Line3'},...
%   'groups', [1 1 2 2 3 3 3 3 3], 'displayedLines', [2 3]);
%
% hgsave(gcf, 'testfig.fig');
% hgload testfig.fig
% clickableLegend


% Extract any arguments for clickableLegend
ind = find(strcmpi(varargin,'DisplayedLines'));
if ~isempty(ind)
    if ind == nargin
        error('The DisplayedLines parameter value must be specified');
    end
    dispflag = true;
    dispinds = varargin{ind+1};
    varargin(ind:ind+1) = [];
else
    dispflag = false;
end

ind = find(strcmpi(varargin,'groups'));
if ~isempty(ind)
    if ind == nargin
        error('The groups parameter value must be specified');
    end
    groupflag = true;
    groupmem = varargin{ind+1};
    varargin(ind:ind+1) = [];
    
    groups = unique(groupmem);
    firstmem = zeros(size(groups));
    if nargin > 0 && ishandle(varargin{1}(1))
        if strcmpi(get(varargin{1}(1),'Type'),'axes')
            hAxes = varargin{1}(1);
            obj = flipud([findobj(hAxes,'Type','line');findobj(hAxes,'Type','patch')]);
        else % It's a line/patch
            obj = varargin{1};
            for i = 1:length(groups)
                firstmem(i) = find(groupmem==groups(i),1);
            end
            varargin{1} = obj(firstmem);
        end
    else
        hAxes = gca;
        obj = flipud([findobj(hAxes,'Type','line');findobj(hAxes,'Type','patch')]);
    end
else
    groupflag = false;
end

% Create legend as if it was called directly
[varargout{1:nargout(@legend)}] = legend(varargin{:});

% Extract what is needed for the rest of the function and fix varargout
[leghan, objhan, plothan] = varargout{1:3}; 
% objhan: strings
% plothan: graphics objects
varargout = varargout(1:nargout);

% At this point, we can quit and behavior would be equivalent to calling
% just legend.

if ~groupflag % Default group membership
    groupmem = 1:length(plothan);
    obj = plothan;
    groups = groupmem;
end

if dispflag % DisplayedLines parameter was passed in
    hidden = true(1, length(plothan));
    dispinds(dispinds>length(plothan)) = [];
    hidden(dispinds) = false;
end

% Set the callbacks
for i = 1:length(plothan)
    set(objhan(i), 'HitTest', 'on', 'ButtonDownFcn',...
        @(varargin)togglevisibility(objhan(i),obj(groupmem==groups(i))),...
        'UserData', true);
    if dispflag && hidden(i)
        togglevisibility(objhan(i), obj(groupmem==groups(i)));
    end
end


function togglevisibility(hObject, obj)
if get(hObject, 'UserData') % It is on, turn it off
    set(hObject, 'Color', (get(hObject, 'Color') + 1)/1.5, 'UserData', false);
    set(obj,'HitTest','off','Visible','off','handlevisibility','off');
else
    set(hObject, 'Color', get(hObject, 'Color')*1.5 - 1, 'UserData', true);
    set(obj, 'HitTest','on','visible','on','handlevisibility','on');
end

Contact us at files@mathworks.com