How to add extra information to figure's legend?
Asked Answered
P

3

6

I want to add extra Information to a figure in MATLAB, like this:

enter image description here

Is it possible? (Of course I want it to be more beautiful)

Permatron answered 10/9, 2013 at 10:35 Comment(7)
You can use LaTeX in the legend labels, would that be sufficient?Gaberdine
Yes, would you please give me LaTeX commands for this purpose?Permatron
So, you want a headed table next to your legend?Gaberdine
@RodyOldenhuis well, I would be interested in how to use latex\how to create a table within the legend... :)Jaehne
@LuciusDomitiusAhenobarbus: not a table of course, but a pretty-printed list of parameter values next to each plot label.Gaberdine
@RodyOldenhuis this wasnt meant to be critic, I'm really interested in this!Jaehne
@LuciusDomitiusAhenobarbus: well, see my answer :)Gaberdine
G
16

I put together something reasonably generic, see below.

I will generalize this a bit more and post it to the File Exchange, I think it's a fairly nice tool to have around :)

I intend to

  • automatically adjust the table size to fit its contents
  • make it suited for arbitrary legend placement
  • couple the table and legend together when moving them with the mouse
  • make the header optional
  • support various types of input

But for now:

% Example input

plot(1,1,'r.', 1.1,1.1', 'b.', 1.2,1.2, 'k.');
legendHandle = legend('plot 1', 'plot 2 with longer title', 'plot 3');

tableHead = {'\theta_0' '\phi' 'df/dx'};
tableContent = rand(3);




% Extract information 
legendPosition = get(legendHandle, 'position');
children = get(legendHandle, 'children');
labels   = children(strcmp(get(children, 'type'), 'text'));


% Basic error traps
if size(tableContent,1) ~= numel(labels)
    error('LegendTable:dimension_mismatch',...
        'Each legend entry must have a corresponding row in the table.')
end

if size(tableHead,2) ~= size(tableContent,2)
    error('LegendTable:dimension_mismatch',...
        'Table header dimensions are inconsistent with table data.');
end

% Convert header & content to cell-array when necessary
if isnumeric(tableContent)
    tableContent = cellfun(@num2str, ...
        num2cell(tableContent), 'UniformOutput', false);
end
if isnumeric(tableHead)
    tableHead = cellfun(@num2str, ...
        num2cell(tableHead), 'UniformOutput', false);
end

% Proper tick locations for the table
xticks = linspace(0, 1, numel(tableHead)+1);
yticks = linspace(0, 1, numel(labels)+2);

% Text positions are in the centers of the table cells
txt_xPositions = xticks(1:end-1) + (xticks(2)-xticks(1))/2;
txt_yPositions = fliplr(yticks(1:end-1) + (yticks(2)-yticks(1))/2);

% Derive correct table position
headerHeight  = legendPosition(4)/numel(labels);
tablePosition = legendPosition + [0 -headerHeight 0 headerHeight];

% Shift position of original legend 
set(legendHandle, 'position', legendPosition + [-tablePosition(3) -headerHeight 0 0])

% Create table
table = axes(...     
    'position', tablePosition,...
    'xtick', xticks,...
    'ytick', yticks,...
    'xticklabel', [],...
    'yticklabel', [],...    
    'gridlinestyle', '-',...
    'box', 'on',...
    'tag', 'LegendTable');
grid on


% Print table header & table entries
kk = 1;
tableTexts = zeros(numel(tableHead)+numel(tableContent),1);
for ii = 1:numel(txt_xPositions)

    % Column header
    tableTexts(kk) = text(txt_xPositions(ii), txt_yPositions(1), tableHead{ii},...
            'parent', table,...
            'HorizontalAlignment', 'center');
    kk = kk + 1;

    % Column content  
    for jj = 1:numel(txt_yPositions)-1
        tableTexts(kk) = text(...
            txt_xPositions(ii), txt_yPositions(jj+1), tableContent{jj,ii},...
            'parent', table,...
            'HorizontalAlignment', 'center');
        kk = kk + 1;
    end 
end

Result:

enter image description here

Gaberdine answered 10/9, 2013 at 16:19 Comment(3)
@SardarUsama i have this error with Matlab R2018a Error using imglegend (line 24) Each legend entry must have a corresponding row in the table. and Error using matlab.graphics.illustration.Legend/set Error setting property 'Position' of class 'Legend': Value must be numeric and finiteStandush
The behavior of legend seems to have changed in newer versions. With the same code, labels don't evaluate to what is intended (R2018a Update-2). The same can be achieved with labels = legendHandle.String;Evidential
@SardarUsama now works. thank you, you were very kind and patient. I'm studying how the code works to understandStandush
J
5

Well perhaps a bit of an overkill:

You could use uitable, like this

%define your data:
 dat =  {'        green', 1, 2;...
    '        blue', 2,3.1;...   
    '        yellow', 3, 4.8;}
columnname =   {' ', 'Param1', 'Param2'};
columnformat = {'char', 'numeric', 'numeric'}; 
t = uitable('Units','normalized','Position',...
        [0.05 0.05 0.755 0.87], 'Data', dat,... 
        'ColumnName', columnname,...
        'ColumnFormat', columnformat,...
        'RowName',[], 'Parent', gcf);

you just need to know the handle, if gcf (get current figure) doesnt work! you can then resize and do whatever you want, to make it look nice...

Jaehne answered 10/9, 2013 at 12:52 Comment(0)
V
0

You can use the num2str function to pass parameters to the legend.

legend(['red ' num2str(param1_red) ' ' num2str(param2_red)], ... )

Volumed answered 10/9, 2013 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.