CroCo
CroCo

Reputation: 5741

How to change the appearance of colored lines for legend

I would like to be able to customize the colored lines in the legend (i.e. bold, width, etc). So far I can change the font size of the text. Is there a way to achieve that?

LegendSize = 30;

x = 0:0.1:pi;
y1 = sin(x);
y2 = cos(x);

plot(x,y1, 'r', x, y2, 'b', 'LineWidth', 2)

h = legend('A', 'B');
set(h,'FontSize',LegendSize,'FontWeight','bold','LineWidth',2);

enter image description here

Upvotes: 1

Views: 625

Answers (1)

mikkola
mikkola

Reputation: 3476

There were major changes in the way MATLAB handles graphics in version R2014b, so I'm splitting this answer to two parts to deal with both of them.

Up to R2014a

In MATLAB versions prior to R2014b, the legend object has a property called Children. This is a list of handles to graphics objects related to the legend, including the lines shown next to the text labels. This Matlab central thread discusses ways to access those children and modify their properties. What you want to do is get the handles to the children, find out which ones of them refer to line objects, and then manipulate their properties accordingly (e.g. by modifying their LineWidth property).

I don't have access to versions of Matlab prior to R2014b currently, but I assume something like this would be appropriate:

%// let h be the handle to the legend object. 
h_children = get(h,'children'); %// get the children of the legend
%// Find all children whose type is 'Line'
h_lines = findobj(h_children, 'Type', 'Line'); 
%// Modify the properties of the children as appropriate, e.g.:
set(h_lines, 'LineWidth', 10);

This leaves any other properties you don't modify in their default values as currently in the legend, but modifies the desired properties to your custom value.

From R2014b onward

Since R2014b, the legend objects no longer have any children whose properties can be modified. You are left with the option of modifying the legend properties manually, but as seen from the documentation linked, these options do not include a way to change the appearance of the lines directly.

There is a possible workaround, however. This solution is not ideal, as you are required to define "extra" line objects, but it gets the job done. The basic strategy is to draw two invisible lines more that have the line properties that are desired to be displayed in the legend. Then the legend is generated referencing those invisible lines instead of the actual ones, allowing different line styles there and in the actual figure.

Whatever properties you set for the invisible lines will be shown in the legend.

Example:

%//Workaround by drawing invisible lines in figure
legend_line_width = 4; %// Desired line width to show in *legend*
legend_line_style = '-'; %//use line style of original plot in legend, too

figure;
plot(x,y1, 'r', x, y2, 'b', 'LineWidth', 2) %// Plot original lines first
hold on; %// prevent deletion of the lines plotted above
%// Draw invisible lines for which we set the legend
h1 = plot(x, y1, 'r', 'visible', 'off', 'LineWidth', legend_line_width, ...
    'LineStyle', legend_line_style);
h2 = plot(x, y1, 'b', 'visible', 'off', 'LineWidth', legend_line_width, ...
    'LineStyle', legend_line_style);
h = legend([h1 h2], 'A', 'B');%// Legend that points to h1 and h2
set(h,'FontSize',LegendSize,'FontWeight','bold'); %// Change other properties

Edit: An improved solution

This works at least for R2015b. I am unsure when this possibility appeared, comments are welcome!

Looking at the documentation of the legend's output arguments, I noticed there is the possibility to extract additional output arguments which provide handles to the line objects drawn. So this removes the need for the workaround above.

Example:

[h, icons, plots, s] = legend('A','B');
%// Find those whose type is line
h_lines = findobj(icons, 'Type', 'Line');
set(h_lines, 'LineWidth', 10); %// modify properties as desired

Upvotes: 1

Related Questions