Code covered by the BSD License  

Highlights from
legendshrink

from legendshrink by Will Robertson
Shrinks the length of the legend lines.

legendshrink(s,align,lg)
function legendshrink(s,align,lg)
% LEGENDSHRINK Shrink the legend lines
%
%   This is important for small plots because the size of the lines is
%   constant irrespective of the physical size of the figure. Only works
%   for vertical legends, for now.
%
%   LEGENDSHRINK(S): adjusts the length of the lines in the legend by
%   scaling factor S < 1. (S = 0.6 if omitted.) All legends in the current
%   figure are affected.
%
%   LEGENDSHRING(S,ALIGN): as above aligning the legend text as specified:
%      ALIGN = 'left' | 'right' | 'centre' | 'best' (default)
%   Default ('best') aligning adapts the alignment based on the 'location'
%   of the legend. The first letter can be used as a shorthand for each.
%
%   LEGENDSHRINK(S,ALIGN,LG): as above for legend handle(s) LG.
%
%   If S or ALIGN are [] then default values are used.
%
% EXAMPLE
%   figure; hold on
%   plot(1:10,'.-'); 
%   plot(10:-1:1,'o-'); 
%   legend({'one' 'two'},'location','north')
%   legendshrink
%
%
% Please report bugs and feature requests for
% this package at the development repository:
%  <http://github.com/wspr/matlabpkg/>
%
% LEGENDSHRINK  v0.2  2009/22/06  Will Robertson
% Licence appended.


%% Input parsing
if nargin < 1 || isempty(s),     s = 0.6;        end
if nargin < 2 || isempty(align), align = 'best'; end
if nargin < 3
  % all legends in the current figure:
  lg = findobj(gcf,'Tag','legend');
end

if isempty(lg)
  warning('LEGENDSHRINK:nolegend',...
    'There is no legend to shrink. Exiting gracefully.');
  return
elseif length(lg) > 1
  % If there are multiple legends then re-call the function for each
  % individual legend handle:
  for ii = 1:length(lg)
    legendshrink(s,align,lg(ii))
  end
  return
end

%% Get parameters
% Will break if children are added to the legend axis. Damn.

lch = get(lg,'Children');
% this allows interaction with labelplot.m:
cch = findobj(lch,'-not','Tag','legendlabel');
cll = findobj(lch,'Tag','legendlabel');

orientation = get(lg,'Orientation');
legendloc = get(lg,'Location'); 
orientvertical = strcmp(orientation,'vertical');

%% Resizing and aligning

if orientvertical
  if align(1)=='l'
    legendtrim = @legendtrimleft;
  elseif align(1)=='r'
    legendtrim = @legendtrimright;
  elseif align(1)=='c'
    legendtrim = @legendtrimcentre;
  else
% Want to ensure that the legend is trimmed away from the side that's being
% aligned to the figure; e.g., if the legend is inside the figure on the
% right, then the left side needs to be trimmed. And vice versa. Centre it
% if unsure. (Perhaps there should be an option to always do this.)
    if ~isempty(regexpi(legendloc,'WestOutside$')) || ...
        ~isempty(regexpi(legendloc,'East$'))
      legendtrim = @legendtrimleft;
    elseif ~isempty(regexpi(legendloc,'EastOutside$')) || ...
        ~isempty(regexpi(legendloc,'West$'))
      legendtrim = @legendtrimright;
    else
      legendtrim = @legendtrimcentre;
    end
  end
else
  warning('LEGENDSHRINK:horizontal',...
    'There is yet no implemented method for shrinking horizontal legends. Exiting gracefully.');
  legendtrim = @legendtrimabort;
end

%% Loop through and adjust the legend children

% hack to get things working for now:
cch_lines = findobj(cch,'Type','Line');
cch_min = find(cch==cch_lines(1));
cch = cch(cch_min:end);
cch_max = 3*floor(length(cch)/3);
cch = cch(1:cch_max);

for ii = 2:3:length(cch)
  %  ii-1  ==  marker handle (line handle)
  %  ii    ==    line handle
  %  ii+1  ==    text handle
  linepos = get(cch(ii),'XData');
  textpos = get(cch(ii+1),'Position');
  linewidth = linepos(2)-linepos(1);
  
  [newlinepos newtextpos] = legendtrim(linepos,textpos);
  
  set(cch(ii-1),'XData',   mean(newlinepos));
  set(cch(ii),  'XData',   newlinepos);
  set(cch(ii+1),'Position',newtextpos);
end

%% Adjust the legend title, if any
% This is provided by labelplot.m (same author)

if ~isempty(cll)
  llpos = get(cll,'Position');
  if isequal(legendtrim,@legendtrimleft)
    llpos(1) = llpos(1)+s*linewidth/2;
  elseif isequal(legendtrim,@legendtrimright)
    llpos(1) = llpos(1)-s*linewidth/2;
  end
  set(cll,'Position',llpos);
end

%% subfunctions

  function [newlinepos newtextpos] = legendtrimleft(linepos,textpos)
    newlinepos = linepos;
    newtextpos = textpos;
    newlinepos(1) = linepos(2)-s*linewidth;
  end
  function [newlinepos newtextpos] = legendtrimright(linepos,textpos)
    newlinepos = linepos;
    newtextpos = textpos;
    newlinepos(2) = linepos(1)+s*linewidth;
    newtextpos(1) = textpos(1)-(linepos(2)-newlinepos(2));
  end
  function [newlinepos newtextpos] = legendtrimcentre(linepos,textpos)
    newlinepos = linepos;
    newtextpos = textpos;
    newtextpos(1) = textpos(1)-(1-s)*linewidth/2;
    newlinepos(1) = linepos(1)+(1-s)*linewidth/2;
    newlinepos(2) = newlinepos(1)+s*linewidth;
  end
  function [newlinepos newtextpos] = legendtrimabort(linepos,textpos)
    newlinepos = linepos;
    newtextpos = textpos;
  end

end

% Copyright (c) 2007-2009, Will Robertson, wspr 81 at gmail dot com
% All rights reserved.
%
% Distributed under the BSD licence in accordance with the wishes of the
% Matlab File Exchange.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in the
%       documentation and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
% EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
% DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
% ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
% THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Contact us at files@mathworks.com