MATLAB Answers

Legend horizontal orientation doesn't work when extracting icon handles

23 views (last 30 days)
Ida
Ida on 21 Dec 2016
Commented: Ida on 22 Dec 2016
Hi! I'm using Matlab 2015b and am trying to make a nice plot with a horizontal legend at the bottom. When I do like below, I get nice results (see figure below).
legendHandle = legend('1st' '2nd' '3rd' '4th' '5th' '6th');
legendHandle.Units = 'centimeters';
legendHandle.Orientation = 'horizontal';
legendHandle.Location = 'southOutside';
However, I want to reduce the legend sample line length, so I take out the handle to the icon objects as well.
[legendHandle,icons,~,~] = legend('1st' '2nd' '3rd' '4th' '5th' '6th');
legendHandle.Units = 'centimeters';
legendHandle.Orientation = 'horizontal';
legendHandle.Location = 'southOutside';
lineSamples = findall(icons,'Type','Line')
for i=1:numel(allSamples)
try
lineSamples(i).XData = [lineSamples(i).XData(1) lineSamples(i).XData(2)*0.5];
end
end
This yields a messed up result however (figure below), where the legends are not horizontal but still vertical but squished together.
Can anyone point me in the right direction how to fix this? Thank you! /Ida

  0 Comments

Sign in to comment.

Accepted Answer

Massimo Zanetti
Massimo Zanetti on 21 Dec 2016
As far as I know the syntax [lgd,icons,plots,txt] = legend(..) is not reccomended. Notice in fact that by simply calling icons as output you destroy the legend layout:
%plot 3 random lines
plot(rand(10,3));
[lh,icons,~,~] = legend('1st','2nd','3rd');
lh.Units = 'centimeters';
lh.Orientation = 'horizontal';
lh.Location = 'southOutside';
Therefore, after calling icons you need to replace ALL the objects in the legend. To do so, consider that icons objects of type 'Line' are twice the number of lines (in this case 6)
ls= findall(icons,'Type','Line')
ls =
6×1 Line array:
Line (1st)
Line (1st)
Line (2nd)
Line (2nd)
Line (3rd)
Line (3rd)
For every line that you see in the legend, you have 2 line objects! In parentheses the corresponding item label is reported by Matlab. For each line, the first object associated to it is the line object which is plotted in the legend, while the second one is its central position (inspect both XData and YData of all ls(k) for k=1,...,6). Thus, to make your custom legend, change all the ls lines XData and YData accordingly (for example, YData must be all the same while XData must be properly spaced). Remember, you also have to adjust text objects position.
My suggestion is to set 'Units' to 'normalized'.
Let me know if you need help.

  4 Comments

Show 1 older comment
Walter Roberson
Walter Roberson on 21 Dec 2016
In the MATLAB release you are using, unless you use the extended output syntax for legend(), the line() objects are not created and so cannot be adjusted. At the moment, I do not recall the exact name of the alternate objects that are created. They are not configurable.
Massimo Zanetti
Massimo Zanetti on 22 Dec 2016
Yes, by now there is no other way than re-adjusting all line and text objects one by one.. :(
However, Matlab indeed does a good job in arranging the objects.. do you really need to change the feel?
Ida
Ida on 22 Dec 2016
Thank you both Walter and Massimo for your input.
Ok, so there's no simple way then. I think I'll just leave it as it is for now then. I'm preparing figures for a scientific paper, and need to save some space and that's why I wanted to shorten the entire legend by shortening the samples (which are uneccessary long in my opinion) and still keep a single row. I may edit the pdf figure in an external software however.
Thank you!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!