9
votes

I have the following picture :

enter image description here

And I would like to make a legend for it. Basically, I want to make a legend for each type of rectangle. In the legend box, I want to mark each color line according to the type of body which it marks:

  • green line : head
  • yellow line : torso
  • purple line : right arm
  • cyan line : left arm
  • red line : left leg
  • blue line : right leg

This is basically custom, because I have more rectangles of each type. How can I do a custom legend and attach it to the figure which draws this picture?

5

5 Answers

2
votes

The simplest way I can think of is to first plot one rectangle of each type and construct a legend for only unique rectangles. Like so:

figure;
hold on;

% unique rectangles
plot(rand(1, 10), 'b');
plot(rand(1, 10), 'g');

% the rest
plot(rand(1, 10), 'b');
plot(rand(1, 10), 'g');

% use normal legend with only as many entries as there are unique rectangles
legend('Blue', 'Green');

You will have many lines of the same color, but a legend only for unique colors.

7
votes

There are 2 ways you could go about this. You could create your squares and then assign them to an hggroup. This way you dont have multiple items for each color. Something like this:

hold on
for ii = 1:4
    hb(ii) = plot(rand(1,2), rand(1,2),'color','r'); 
end

hg = hggroup;
set(hb,'Parent',hg) 
set(hg,'Displayname','Legs')

legend(hg)

Or you could create dummy objects, like this:

hold on
for ii = 1:4
    hb(ii) = plot(rand(1,2), rand(1,2),'color','r'); 
end

p = plot([],[],'r');

legend(p,'Legs')

The former is a little more elegant.

3
votes

I would like to add to dvreed77's answer on using hggroup that for clean legend use, I also needed to set the 'IconDisplayStyle' (Matlab R2014a), such that:

%4 kinds of lines:
n_areas = 4;
n_lines = 10;

%use built-in color map
cmap = hsv(n_areas);

%plot lines and generate handle vectors
h_fig = figure;
hold on
h_lines = zeros(1,n_lines);

for l = 1:n_areas

  for k = 1:n_lines
    h_lines(k) = plot(rand(1,2), rand(1,2),'Color',cmap(l,:));
  end

  %Create hggroup and set 'icondistplaystyle' to on for legend
  curPlotSet = hggroup;
  set(h_lines,'Parent',curPlotSet);
  set(get(get(curPlotSet,'Annotation'),'LegendInformation'),...
      'IconDisplayStyle','on');
end

%Now manually define legend label
legend('heads','legs','hands','feet')
1
votes

Just draw legend dots outside the plot:

figure;
plot(-1,-1,'gs',-1,-1,'b^',-1,-1,'ro');
legend('x1','x2','x3','Location','NorthWest');
xlim([0,1]); ylim([0,1]);
0
votes

To control the appearance of legend entries, plot points that have values which are NaN then pass the objects returned by plot and an array of labels to the legend function (NaN points are not visible in the plot, but appear in the legend).

colors = ["red", "blue"];
labels = ["this is red", "this is blue"];

% We 'plot' a invisible dummy point (NaN values are not visible in plots), 
% which provides the line and marker appearance for the corresponding legend entry.
p1 = plot(nan, nan, colors(1));
hold on 
p2 = plot(nan, nan, colors(2));

% Plot the actual plots. You can change the order of the next two function calls 
% without affecting the legend.
plot([0, 1], [0, 1], colors(1));
plot([0, 1], [1, 0], colors(2)); 

legend([p1, p2], labels)

If the plots in [p1, p2] are not in the current figure when legend([p1, p2], labels) is called, then it will raise the following error:

Invalid argument. Type 'help legend' for more information.

You can filter plots that are not in the current figure using something like this:

plots_in_figure = findall(gcf,'Type','Line');
plots_for_legend_indices = ismember([p1, p2],  plots_in_figure);
plots_for_this_legend = this.plots_for_legend(plots_for_legend_indices);

legend(plots_for_this_legend, labels)