Search code examples
matlabmatlab-figurelegendlegend-properties

How to decrease the size of the legend in a figure?


The following code plots a figure. The code should work on Matlab >= R2014b. I want to remove the space within the legend. How to do this?

x = 0:0.5:10;
figure; hold on;
plot(x,sin(x), 'Marker', 'o');
plot(x,cos(x), 'Marker', 's');
[leg, objs] = legend({'sin', 'cos'}, 'Location', 'SouthWest');
line_start_end = [0.01, 0.4];
line_text_step = 0.01;
% for each line, text object, adjust their position in legend
for i = 1:numel(objs)   
  if strcmp(get(objs(i), 'Type'), 'line')
    % line object
    if 2 == numel(get(objs(i), 'XData')) % line 
      set(objs(i), 'XData', line_start_end);
    else % marker on line
      set(objs(i), 'XData', sum(line_start_end)/2);
    end
  else
    %text object
    text_pos = get(objs(i), 'Position');
    text_pos(1) = line_start_end(2) + line_text_step;
    set(objs(i), 'Position', text_pos);
  end
end

See the following result:

result

What I want is :

required


Solution

  • As @Sardar Usama suggested, I put my solution here. I hope it is useful for you.

    The first answer is nice. However, I finally use the following code to do this task.

    close all
    
    x = 0:0.5:10;
    figure; hold on;
    ph(1) = plot(x,sin(x), 'Marker', 'o');
    ph(2) = plot(x,cos(x), 'Marker', 's');
    
    ax = gca;
    ax.Box = 'on';
    
    bx = axes('position', [ax.Position(1:2), 0.3, 0.4], 'Box', 'on', 'XTick', [], 'YTick', []);%, 'Color', [0.8549,0.7020,1.0000]);
    cx = axes('position', [ax.Position(1:2), 0.3, 0.4], 'Box', 'on', 'XTick', [], 'YTick', []);%, 'Color', [0.8549,0.5020,1.0000]);
    
    [legb, objsb] = legend(bx, ph, {'sin', 'cos'}, 'Location', 'SouthWest');
    [legc, objsc] = legend(cx, ph, {'sin', 'cos'}, 'Location', 'SouthWest');
    
    line_start_end = [0.01, 0.3];
    line_text_step = 0.05;
    
    legendshrink(ax.Position(1:2), legb, objsb, bx, line_start_end, line_text_step);
    legendshrink(ax.Position(1:2), legc, objsc, cx, line_start_end, line_text_step);
    
    % you need only to adjust cx' position.
    cx.Position(1:2) = [ax.Position(1)+ax.Position(3)-cx.Position(3), ax.Position(2)];
    legc.Position(1:2) = cx.Position(1:2);
    

    where legendshrink is defined as:

    function legendshrink(leg_pos_xy, leg, objs, bx, line_start_end, line_text_step)
    
    % leg_post_xy = ax.Position(1:2);
    % [leg, objs] = legend(bx, line_handles, text_cell);
    % line_start_end = [0.01, 0.4];
    % line_text_step = 0.01;
    
    % for each line, text object, adjust their position in legend
    for i = 1:numel(objs)
      if strcmp(get(objs(i), 'Type'), 'line')
        % line object
        if 2 == numel(get(objs(i), 'XData')) % line 
          set(objs(i), 'XData', line_start_end);
        else % marker on line
          set(objs(i), 'XData', sum(line_start_end)/2);
        end
      else
        %text object
        text_pos = get(objs(i), 'Position');
        text_pos(1) = line_start_end(2) + line_text_step;
        set(objs(i), 'Position', text_pos);
      end
    end
    
    % get minimum possible width and height
    legend_width_no_right = 0;
    for i = 1:numel(objs)
      % legend margin left
      if strcmp(get(objs(i), 'Type'), 'line')
        if numel(get(objs(i), 'XData')) == 2
          leg_margin_x = get(objs(i), 'XData');
          leg_margin_x = leg_margin_x(1)*leg.Position(3);
        end
      else
        cur_right = get(objs(i), 'Extent');
        cur_right = (cur_right(1)+cur_right(3))*leg.Position(3);
        if cur_right > legend_width_no_right
          legend_width_no_right = cur_right;
        end
      end
    end
    legend_width  = legend_width_no_right + leg_margin_x;
    legend_height = leg.Position(4);
    
    bx.Position = [leg_pos_xy, legend_width, legend_height];
    leg.Position(1:2) = bx.Position(1:2);
    leg.Box = 'off';
    
    end
    

    resulting

    enter image description here