File Exchange

## gridLegend - a multi column format for legends

version 1.4 (5.3 KB) by

Plot a multicolumn format legend.

Updated

On a plot with a lot of traces the standard legend will often scroll off the bottom or the side of the figure, this function is intended to overcome this by allowing the user to define a multi column format for the legend.
Usage :
legHdl = gridLegend(hdl,nCols,gKey,'parameter_name','parameter_value',...);
Inputs :
hdl - a vector of graphic handles of the plotted data
nCols - the number of columns in the legend. (defaults to 2 if not defined)
gKey - a cell array of strings to display which should match the number of graphic handles in hdl (optional)
'parameter_name','parameter_value' - any parameter name pairs applicable to the legend
Output :
legHdl - a vector of graphic handles for the legend generated.
Notes :
By default the legend will be arranged vertically, ie the second legend trace is placed under the first trace, filling the first column before moving onto the next. If you use the 'Orientation','Horizontal' parameter pair then the traces will be arranged horizontally, so the second trace will be in the second
column and so on to the end of the row, then moving down to the next row.
The parameter name / value pairs are passed over to the legend function so you can set things like 'Fontsize',8 etc.

The parameter / name pair of location can be used to place the legend - available options are
'location','bestoutside' : for 2 column legend uses 'eastoutside', more than 2 it uses 'southoutside'
'location','north' : places the legend centrally at the top of the axes
'location','northoutside' : places the legend centrally at the top of the figure
'location','eastoutside' : places the legend on the right of the figure
'location','southoutside' : places the legend centrally at the bottom of the figure
'location','westoutside' : places the legend on the left of the figure

By default this is set to 'bestoutside'

This will work on x-y plots, bar and errorbar charts.

With many traces it's sometimes difficult to work out which trace the legend is referring to. From the MATLAB file exchange I've used a function called 'clickableLegend' which allows you to switch the plotted data on and off by clicking on the Legend key. This function will use clickableLegend if it can find it in your MATLAB path, otherwise it will revert back to the standard legend function.

Examples :

This will plot a vertical legend with two columns
gridLegend(hdl,2)

This will plot a horizontal legend, 8 traces per row, and fontsize set to 8 points.
gridLegend(hdl,8,gKey,'Orientation','Horizontal','Fontsize',8)

This will plot a vertical legend on the left hand side with 2 columns with the box switched off.
gridLegend(hdl,2,gKey,'location','westoutside','Fontsize',8,'Box','off')

Note with versions earlier than R1014b you have to fiddle with the XColor and YColor
otherwise we end up with black lines for the X and Y axis.
gridLegend(hdl,2,gKey,'location','westoutside','Fontsize',8,'Box','off','XColor',[1 1 1],'YColor',[1 1 1])

enzo0706

### enzo0706 (view profile)

It's a great tool. However, it is not compatible with R2017a. It seems that in the latest release of MATLAB, they removed the 'dataaspectratio' property of the Legend class. So an error occurs when the function calls to set this property in line 232.

Eugenio

Amy

### Amy (view profile)

Echoing Tobias Haase's comment below. Fontsize does not change the font of the legend text, but does change the size of the legend box.

Georg Söllinger

### Georg Söllinger (view profile)

Great Function!
Could it be, that the gridLegend doesnot work with fill?

Daisy Wan

### Daisy Wan (view profile)

Thanks for this great function.
I experience a issue with bar chart.
After saving the resulted plot to svg, a white diagional dotted line appear on each legend item, looking as if the rectangle is formed by 2 triangle. Any insight on workaround would be appreciated. I am working with matlab 2015b.

PANAGIOTIS EVANGELIOU

Hsieh-Chi Chang

### Hsieh-Chi Chang (view profile)

I have a question. The works in legend box exceed the boundary. How do I change the box size to fit words? Thank you.

Jacob D

### Jacob D (view profile)

It would also be good, if, like the Matlab legend() function, object_h is returned too.

Jacob D

### Jacob D (view profile)

Units of the legend and axes objects should be set the same prior to measurements and changes in the current code. Otherwise, mismatched units will cause offsets to be miscalculated.
A fix:

[legend_h,object_h] = fLegend(hdl,varargin{:});
origLegUnits = get(legend_h, 'units');
set(legend_h, 'units','points');

axHdl=get(hdl(1),'Parent');
origAxUnits = get(axHdl, 'units');
set(axHdl, 'units','points');

%% Additional Code 3 (at end of function)
% Reset units
set(legend_h, 'units',origLegUnits);
set(axHdl, 'units',origAxUnits);
return

Hi,

hLegend = gridLegend(H(1:4),2,LEGEND(1:4),'Location',LegendPos,'Box','off');

Using the above code gives me the below error on R2016R:

Warning: Ignoring extra legend entries.
> In legend>set_children_and_strings (line 643)
In legend>make_legend (line 328)
In legend (line 257)
In gridLegend (line 109)
In plot_DTI_motion_parc (line 99)
Undefined operator '<' for input arguments of type 'cell'.

Error in gridLegend (line 114)
if gd < 2,

Error in plot_DTI_motion_parc (line 99)
hLegend = gridLegend(H(1:4),LEGEND(1:4),'Location',LegendPos,'Box','off'); %% removing the outter box of the legend

LEGEND is a 1x4 cell which contains the legend labels in it.

Tobias Haase

### Tobias Haase (view profile)

I have some troubles using your otherwise great function with Matlab 2015 and Matlab 2016.
The handover of Fontsize is not working anymore. Anytime I tried to change Fontsize (same with your DEMO file) the spaces between the different entries will change but the fontsize itself will not change at all. There is no error posted by Matlab software. However, the other specs as e.g. box on/off etc. will work perfectly.
Do you or another member here have any idea how it could work?? Thank you for your help!

Best regards
Tobi

Marc L.

### Marc L. (view profile)

Works great!

However, it doesn't seem to work when adding the Latex Interpreter parameter (i.e. calling for example gridLegend(hdl,3,array_params,'Interpreter','Latex');)

Is there a solution to this problem?

Keah Ying Lim

Keah Ying Lim

### Keah Ying Lim (view profile)

Alessandro Masullo

Perfect!

SabrinaP

### SabrinaP (view profile)

I really like this function, it works great. The only issue I have is that the box of the legend is not centered with the subplots/plots. Is there a way you can fix that easily? Also, when I save it (using print function), the legend box appears over the plot box, just a little bit on the end. The format I have set is 5 horizontal subplots and each has its own legend to the right side in 2 columns.

Felix Burget

### Felix Burget (view profile)

i am using the gridLegend as follows

gridLegend(hdl,5,planner_legend_names,'location','southoutside','Orientation','Horizontal','Fontsize',8);

where "planner_legend_names" is a cell array of legend names. Everything works fine for locations other than 'southoutside'. For the 'southoutside' setting the legend box covers the X-axis label and when the number of columns is 5 (or more) the pdf truncates the box of the legend on the left and right side. Is it possible to manually shift the legend box further down in order to not cover the Xaxis label. For the issue related to the number of columns I am ok with rearranging the legends to less than 5.
Felix

Hi Felix,
Normally it works fine for me to pdf and I'm struggling to get a test case which does truncate the legend. What version of MATLAB are you using? and number of lines plotted and any particular options, particularly location, would be useful to replicate the problem.

Felix Burget

### Felix Burget (view profile)

is it possible to properly export the graphics afterwards, e.g. to pdf. I tried using

saveas(gcf,'eval.pdf');

but the resulting pdf truncates the legend. Do I have to follow another way in order to export it as a vector graphics?

Felix

Christian

### Christian (view profile)

Hi Adrian, that works! Thanks for this. Makes my plots look much nicer!

Christian

### Christian (view profile)

Hi Christian, many thanks for the feedback and for spotting the problem with the north location, it is one I had missed. Version 1.4 corrects this, calculated from the axes position and height to keep it inside the axes for different column numbers. Please let me know if this works for you. Adrian

Christian

### Christian (view profile)

This is a very convenient function! However, I've noticed using R2015a is that location "north" does not sit in my axes, but rather the top bar of the axes bisects the legend. I alleviated it by changing the height parameter in the position to lower the position from AxPosOut(4) by double the new height of the legend. Thanks!

Latest version (1.3) should now work with subplots. The demo file has an example.

The legend function no longer uses an additional set of axes to create the legend hence the problem with the dataaspectratio. After a bit of fiddling I found a way to hack it using fontsizes. So I've managed to test it ok on R2014b, hopefully someone can let me know if it works ok on R2015a/b.

Matias Lopez Abukalil

### Matias Lopez Abukalil (view profile)

It sounds like a great file. However, I had the same problem that Nicholas using MATLAB2015a.

Has anyone found a solution for this?

Simon Woodward

### Simon Woodward (view profile)

Good job!

I have a scatter plot and am putting the legend at SouthOutside. It seems when the number of series is not a multiple of the number of columns, the legend is positioned so that the left hand edge is cut off. Any way to fix this?

Cheers

Nicholas

### Nicholas (view profile)

It seems that the 'dataaspectratio' property of legends has been removed in recent releases of matlab

I'm using 2014b and can not find this property, your function errors on line 232: set(legend_h,'dataaspectratio',[width/gd gd/numpercolumn 1]);

Any thoughts or suggestions around this would be helpful

Shuqin

### Shuqin (view profile)

Wonderful! I think you solved the problem that many paper writer need to face. Thanks!

Mahdi Ebrahimian

### Mahdi Ebrahimian (view profile)

Thanks for the nice function.
I want to have a row legend (three columns one row) but when I put column number equal to three I get an error message.
"Can't work out what sort of legend we've got - sorry bailing out"

Any suggestions to fix this?

Todd

### Todd (view profile)

Very easy to use and helpful. Thanks.

Benedikt F

### Benedikt F (view profile)

Did not work for a figure containing both error bar and x-y plots

James

### James (view profile)

Works very well, except when the figure is saved as a fig file. When the saved file is opened, the legend has reverted to single column. Recommendations for how to fix this issue appreciated.

Amanda

### Amanda (view profile)

Hi, I love this function! My one big issue is that I sometimes find it hard to define a handle for the plotted data. Especially for compound graphs like a bar chart with error bars.

I get error for too many output arguments.

I am new to matlab so I hope someone could help me out here. Thank you!

laoya

### laoya (view profile)

Great jobs, thanks!
I wish the function support 'Best' like the legend function of matlab.

Edward Byers

### Edward Byers (view profile)

Doesn't work perfectly for subplots but...
I managed to get it to work reasonably well (on 1 occasion with an Area subplot) by...:
1) - Open gridLegend .m file and comment/delete line 273.
2) - If you are getting errors about Scribelegend, delete lines 278-284
3) - Specify a location (I used 'location','southoutside' )

Basically the issue with subplots (from what I can see) is that gridLegend is trying to control the 'gca' which doesn't seem to exist in subplots.

Nicky

### Nicky (view profile)

gridLegend doesn't seem to work when the figure contains subplots (it messes up the sizes of the subplots).
Is there any fix for this?

Jim

### Jim (view profile)

This is a nice improvement in capability over columnLegend. Unfortunately, despite turning off the ScribeLegendListeners properties, I find that when a figure is saved and later reopened, the legend reverts to single-column format. My code has two calls to saveas near the end, one to save the figure in .fig format, and one to save it as a .emf file. Both are afflicted with single-column disease.

Johnny

### Johnny (view profile)

Is there any way to adjust the spacing between two columns? Thanks.

Matthias Pospiech

### Matthias Pospiech (view profile)

The script fails for my patch plots completely:

Index exceeds matrix dimensions.

Error in gridLegend (line 206)
set(object_h(linenum), 'ydata', [height-position*sheight height-position*sheight]);

Error in testplot (line 204)
legHdl = gridLegend(hplot,2,ltext)

with hplot and ltext both of size 1x6

J G

### J G (view profile)

Hi there, will this work on scatter plots? Thanks!

Bob Sturm

Well done!

sarah

### sarah (view profile)

Any chance this can work for graphs including both lines and bars?

So far an example below doesn't produce a nice legend.

figure;
x=1:10;
y=[2 3]'*x.^.5;
z=2-sin(x);
p=plot(x,y); hold on
b=bar(x,z);
gridlegend([p;b],2, {'line1' 'line2' 'bar'});

James Hickey

Ruben

### Ruben (view profile)

great idea, but the legend placement seems to go haywire. (at least in my case, where location is northoutside, 3 legend entries, 2 columns). Also some of the text and lines overlap.

L1 = {'Flapping angle $\Phi$ ' ,'Elevation angle $\theta$ ',...
'Feathering angle $\alpha$ '};
LH = gridLegend(fh,2,L1,'location','northoutside');

Will DeShazer

### Will DeShazer (view profile)

I have found a collision. I have personalized my 'DefaultFigurePosition' to increase the figure window when it launches. It looks like:scrz=get(0,'ScreenSize');
xscale=0.9;
yscale=0.80;
newxpos=scrz(3)*(1-xscale)/2;
newypos=scrz(4)*(1-yscale)/2-30;
set(0,'DefaultFigurePosition',[newxpos newypos xscale*scrz(3) yscale*scrz(4)]);

With this preference active, gridLegend generates a legend in which the text gets bunched up. As an example of something that gets bunched up:

a=[40 40 40 40:-1:21; 50 50 50 50:-1:31; 60 60 60 60:-1:41];
ndim=size(a,2);

b=[1 2 3 ones(1,ndim-3)*4; 2 3 4 ones(1,ndim-3)*5; 3 4 5 ones(1,ndim-3)*6];

phdl=plot(b,a);

l=cell(1,ndim);
for i=1:ndim
l{i}=sprintf('Label %02i',i);
end

gridLegend(phdl,4,l,'Location','SouthEast','Fontsize',16);

Can this be resolved easily or am I going to have to live with not using 'DefaultFigurePosition' when I want to use gridLegend?

Thanks.

George

### George (view profile)

Hi there,

This function is really useful.

The only problem that I have with it is height of the legend just stays the same size, and the color bans are proportioned.

Eg. I have 9x1 legend originally and I want a 3x3 legend after running it through the function. I want the legend to be a 3rd of the original height and 3 times the original width/length. I want the legend to be compact rather than having heaps of white space

Hi Robin,

Sorry to hear that my routine has trouble with the long legend titles, I've had a quick look at it and I can see where the problem lies. It's possible to apply a quick fix it but then it messes up the short titles.

My first suggestion in the specific example you have posted is to just use the standard legend function in MATLAB, if you apply the 'orientation','horizontal' pair to legend then you'll get a one row, two column legend.

Obviously this won't help if you want a 2x2 legend with long titles. In this case for the minute you'll have to tweak the code.

At line 232

% resize the data aspect ratio to match the new shape.
set(legend_h,'dataaspectratio',[width/gd gd/numpercolumn 1]);

You'll need to tweak the aspect ratio, in your case factor the y-axis by 4.
% resize the data aspect ratio to match the new shape.
set(legend_h,'dataaspectratio',[width/gd 4*gd/numpercolumn 1]);

I'm still looking at improving the calculation so that it'll do it automatically but for the minute I hope this helps.

Regards

Robin Jens

Robin Jens

### Robin Jens (view profile)

I have a problems with placing the labels in two columns when the strings are very long. As example:

figure(2)
x=1:0.1:100;
y=[2 3]'*x.^2;
hdlY=plot(y')
gridLegend(hdlY,2,{'This is the most expensive beer in the world' 'This is the most cheapest bear in the world'},'location','southoutside')

Matthias Pospiech

### Matthias Pospiech (view profile)

The legend gets complete messed up once I apply any property of the fonts

hLegend = gridLegend(hplot,5,{legendStr}, 'FontSize' , FontSize - 2);

here the strings are outside of the legend box all written on top of each other, and the markers are not visible.

If this would work, I would apply 5 stars!

Riccardo

### Riccardo (view profile)

Vey useful. Thanks for sharing

Celine Cluzel

### Celine Cluzel (view profile)

thanks for uploading this. Very nice combination of clickableLegend and columnlegend. Seems to work very nicely with 'plot' graphs.
I'm trying to use it for bar charts - some problems so far with color of bars changing when clicking on the legend. I will come back with a specific question once I've identified what is the problem - if any.
Thank you
Celine