File Exchange

image thumbnail


version (50.9 KB) by Simon Henin
Creates a legend with a specified number of columns


Updated 08 Jan 2020

From GitHub

View Version History

View license on GitHub

Editor's Note: This file was selected as MATLAB Central Pick of the Week

As of Matlab 2018a, legend() now supports columns, so function will no longer be maintained:

Updated 9/8/16: Added new legend positions (e.g. northeastoutside) and better positioning.
numlines = 5;
r = rand(10,numlines);
columnlegend(2, cellstr(num2str([1:numlines]')), 'location', 'northeastoutside');

PRINTING: If you want to print the figure, you'll have to use a command line printer (e.g. export_fig) as the File->Print option embedded in the figure resets the figure properties including the legend

Cite As

Simon Henin (2021). simonhenin/columnlegend (, GitHub. Retrieved .

Comments and Ratings (192)


it can not work

Adam Danz

As of Matlab r2018a, multi-column legends are supported by Matlab's built-in legend function.

To learn how to edit properties of the legend produced by this function in Matlab releases prior to r2018a, see the link below. Special thanks to Simon Henin for leading the initiative in multi-column legends.

Hamdullah Livaoglu

at last i found the error; it doesnt work when there is a patch object in the legend.

Simon Henin


Seems to work fine for me:

figure; plot(rand(10, 6));

FYI. As of Matlab 2018a, legend() now supports columns, so I will no longer be maintaining this code:

Hamdullah Livaoglu

it does not work on handled figure; it extends the legend rather than spliting it...


Hamdullah Livaoglu

Jörn Vogelsang

Marko Peric

Could anyone resolve this issue (that has already been posted here by few users):

Index exceeds matrix dimensions.
Error in columnlegend (line 110)
sheight = vertices_1(2,2)-vertices_1(1,2);

Simon Vanpaemel

Andrea Nygren



I suggest the bugfix
location = lower(varargin{i+1});

Currently it does not allow 'south' to be written 'South', as Sarah Pasternak(30 Nov 2017) has pointed out already.
Otherwise, thanks for the great submission.

Jens Lindahl

Great helper! However, it seems that the legend box doesn't render right when altering the padding.

Jens Lindahl

@Mingxuan: Use the parameter 'fontname' (should be lower case)


how to change fontname?

Kévin Gautier

You saved my intern's life using Matlab R2017b ^^


Hi, this is really great. But I think there is a bug. It can't be used with errorbar.


This function would get 5 stars, the only problem is that you cannot easily alter the spacing between columns. Would it be possible to add this functionality please?

Manuel Kuder


Joan Marc Rodriguez

Baolei Wu

@Simon Thanks for the reply.
I think the "padding" input is only for reducing vertical spaces between entries.
I actually would like to reduce the room between the marker and the instruction text in each entry.
Will it be possible?
Thank you.

Simon Henin


There is a "padding" input option that allows you to add some extra padding between legend elements. You can use negative padding to bring entries closer together.

Baolei Wu

It's really useful! Thank you, Simon.
Is there a way to minimize the spacing between the sign and the text and/or between columns? It will be very helpful since most people use this columnlegend to save the page layout.

Looking forward to your responses.

Simon Henin


This seems to be a bug with the legend function when extra input arguments are passed. In version <2017a, the fontsize doesn't render, and the handles to legend objects are lost. I suggest modifying the fontsize after the call to the function. Something like:

plot(rand(10, 5));
[handle,legend_objects]=columnlegend(3, cellstr(num2str([1:5]')));
pause(0.1); % <- note the pause here. It is required to make sure the legend has fully rendered
set(findall(legend_objects, 'type', 'text'), 'fontsize', 20);

Hope this helps


@Simon Henin
I am using Matlab 2016a.

Simon Henin


I can't seem to reproduce the issue:

plot(rand(10, 5));
columnlegend(3, cellstr(num2str([1:5]')), 'location', 'southwest', 'fontsize', 30);

works fine for me. What version of MATLAB are you using?


I think the problem from this line:
if ~isempty(extravars),
[legend_h,object_h,plot_h,text_strings] = legend(str, extravars{:});

Fof example, If I set
legend_h = legend(str, extravars{:},'FontSize',22);
I can change the font size but if
[legend_h,object_h,plot_h,text_strings] = legend(str, extravars{:},'FontSize',22);
It would not work. Can you help to explain why?

Simon Henin


Just pass fontsize as a name-value argument to the function:

l = columnlegend(2, str, 'fontsize', 18);

Lukas Hagmeyer

Hi Simon.. nice job, but I think the FontSize doesnt work properly or is it just my fault...
l = columnlegend(2, str);
l.FontSize = 18;
The columns will expand the size but the FontSize doesnt really change..

Simon Henin


You need to use the print command from the command line (print('myfigure.png', '-dpng') ) or another command line printer like export_fig. Using File->save as, causes strange rendering problems.

Matthew Getzin

Just as an edit to my last comment, the LiveFigure doesn't show the legend as having two columns, but if I run the script from a .m file the output is the same as the saved figure (two columns bad spacing). Additionally, it looks like the 'boxon' parameter puts the box in the right place, but not the legend entries...

Matthew Getzin

I just realized that when I save the figure, the legend has two columns (the spacing is poor). However, just viewing the figure it does not have two columns.

Simon Henin


Do you have a code sample and/or image of the result? I'm not quite getting the issue, so some sample code would be helpful.

Are you using a latex text interpreter? This may override the fontwieght property.

Matthew Getzin

Hi Simon,
This code looks to be exactly what I am looking for, but when I try to implement it the legend seemingly scoots over a column, but none of the entries occupy the space of the second column. I tried doing some debugging, but I couldn't seem to find where the fix is needed. In the 'line' type, the object_h x/ydata are being updated, but nothing moves.
Any help on this?

King Northland

Hi Simon,
I forgot to say that I also tried your suggestion before: columnlegend2(2, legend,'fontweight','bold','boxon'), where legend is the list of my names in a cell. However, the legend is still shown as without font weight. Logically speaking, I know it should work, but still couldn't figure it out what is the cause of this. Is there another trick or way around this problem that you can think of?

Simon Henin


Simply pass it as an argument. The function takes the same Name-Value pairs as regular legend. So,

columnlegend(2, {'label1', 'label2', 'label3'}, 'fontweight', 'bold');

King Northland

Hi, I cannot change the font weight of the legend. I use set function to allocate the font weight for the legend_h: set(legend_h, 'FontWeight', 'bold'). It didn't work.
I also defined font weight as a case at the beginning of the code, but it's still not happening. Can you give me some hints, so I cane change the font weight.

Asadur Rahman

Simon Henin


I just updated the script to handle this special case of mixing line/errorbar plots. Hope it works for you.

Lisa Schlüter

Hi Simon,
very nice addon! Sadly when I combine an errorbar plot and some norml plots, it doesn't work for me and I get the error message:
Index exceeds array bounds.
Error in columnlegend (line 119)
child2 = child2(2);
What am I doing wrong?
My example code:
y2 = repmat(y1,numel(x),1);
leg_str = cell(numel(x),1);

leg_str{1} = 'errorbar';
hold on
for i=1:numel(x)
leg_str{i+1} = sprintf('plot %u',i);

William Briers

Hi Simon, if I use your function in a Live Script it doesn't work, but if I cut and paste the code (or use your example from the function comments) into the command window it works.
plot(bsxfun(@times, [0:9]',[1:10]));
columnlegend(3, cellstr(num2str([1:10]')), 'location','northwest');

Simon Henin

@M G (Laura)

It should work with errorbar plots as well. As an example, try:

errorbar(1:3, rand(3, 1), rand(3, 1)); hold on;
errorbar(1:3, rand(3, 1), rand(3, 1));
columnlegend(2, {'ErrorBar 1', 'ErrorBar 2'});


Hi Simon,
well I think it's because I am using errorbar and not plot. With plot it works totally fine. Is there a possibility to use errorbar instead of plot?
Thanks, Laura =)

Nathan De Kerpel

Hi Simon,

Thank you for the nice code. It works perfectly for my purpose. I noticed maybe a small bug or could be because I'm working in Matlab R2011. When using the saveas command it is possible to properly save the plots and legends made using this command but when manually saving the figure as a jpg file, the legend is reordered vertically. An easy work around is to save the figure programmatically but I just wanted to inform you on the (minor) issue with the code.

Kind regards,

PS: quick example:
columnlegend(3,{'Plot A', 'Plot B', 'Plot C'})

saving the same figure manually as Trial2.jpg shows the difference I am talking about.

Nathan De Kerpel

Brian Liu

@Simon, it's really amazing, thanks again!

Brian Liu

Thanks a lot, Simon!

Simon Henin


Fixed the bug. You can re-download for functional version.

Brian Liu

By the way, the Matlab version is 2017b.


Brian Liu

Hi Simon, thanks for providing the codes. However, it seems not to work...

>> plot(bsxfun(@times, [0:9]',[1:10]));
columnlegend(3, cellstr(num2str([1:10]')), 'location','northwest');

Cell contents reference from a non-cell array object.
Error in columnlegend (line 67)
[legend_h,object_h,plot_h,text_strings] = legend(str, extravars{:});

yijun xiang



Simon Henin

@Frederick, @Auryn_

I've updated the function to support errorbar plots and allow for optional inputs supported by legend, such as 'fontsize'.
For example:

errorbar(rand(10, 5), rand(10, 5));
columnlegend(3, {'1', '2', '3', '4', '5'}, 'location', 'northoutside', 'fontsize', 18);


I am trying to plot multiple lines with the function errorbar (it works). Then I want to use multicolumn for the legend, but this does not work. It works if I use plot instead of errorbar though.
This is the error I receive when using columnlegend (which works when using plot instead of errorbar):

Error using There is no vertices property on the Group class. Error in columnlegend (line 97) vertices_1 = get(child, 'vertices');

Frederick Wells

Hi, is there a way to adjust font size in columnlegend?

Steve Carroll

I solved it already Simon, I just set the 'padding' to zero :)
Function works perfect, many thanks for sharing it

Simon Henin


You seem to be using a function (maxfig), which maximizes the axes within the figure window. Does it work if you don't use maxfig?

Steve Carroll

Hi Simon

When setting 'Location' as 'SouthOutside', part of my legend is not shown because it is below the graph limits. There is also a big blank gap between the bottom of the x axis and the top of my legend. Could you help please?

Many thanks

Selim ilhan

Hi Simon,
i m using Matlab2017b


I got an error saying:

Error using
Error setting property 'Position' of class 'Axes':
Width and height must be greater than or equal to 0
Error in columnlegend (line 205)
set(gca, 'position', [fig_pos]-[0 -pos(4) 0 pos(4)]);


kuldeep chaudhary

worked just fine; awesome! thanks

Negin Nazarian

Hi Simon,
Do you know how to get around the following error?
The name 'vertices' is not an accessible property for an instance of class 'hggroup'.

Simon Henin


I cannot seem to recreate your issue. If I do:

plot(rand(100, 5)); [legend_h,object_h]=columnlegend(3, {'h_1' 'h_2' 'h_3' 'h_4' 'h_5'}, 'Location', 'Southoutside');

Seems to work fine. What version of MATLAB are you using? What is the exact error from MATLAB? Are their any details about the legend entries, e.g. they are very long text, or include special characters?

Tiago Dias

Dear Simon,

I got a function to make plots with the desired format I want.
function out = plotgeral(Y,Y1,Y2,Y3,Y4,Y5,eixoX,eixoY,titulo,legenda,legenda1,legenda2,legenda3,legenda4,legenda5)

where legenda to legenda 5 are the names of the legend for each Y I plot.

i made :
legend([out out1 out2 out3 out4 out5],legenda,legenda1,legenda2,legenda3,legenda4,legenda5,'Location','SouthOutside','Orientation','Vertical');

but it is to big, i changed to horizontal and it is to large, so i wanted to place the legend under 2 ou 3 columns.

So in my function i called yours but it doesnt work, i wrote this:

str = {legenda,legenda1,legenda2,legenda3,legenda4,legenda5}

I got an error saying the position values must be between 0 and 1.

Amra Rajuli

Thank you simon

Simon Henin


You could just pass the first two legend entries:

line_handles = plot(rand(100, 10));
columnlegend(2,{'a','b'}); % this will only add the first 2 lines to the legend.

Amra Rajuli

Dear Simon, how to use the subset entry legend on this function? for instance, I just want to show L1 and L2 in legend entry. I used this:
columnlegend(2,[L1 L2 L3 L4 L5],{'a','b', 'c', 'd','e'},'Location','northeast');.. But this not work. Thank you


Simon Henin

@ Deepak
Not at this time, but you can do the same thing by just setting the current focus to your axes. e.g. axes(AX); cloumnlegend(...);
@ Namira
You need to pass a cell array of legend strings: columnlegend(2, {'a', 'b', 'c', 'd', 'e', 'f', ‘g’,’h’,’i’,’j’}, 'location', 'northeastoutside')

Deepak Ingole

Dear Simon,
Is there any way to set input argument as specific axes. I want to give legend to specific axes like "legend(target,__)". I am using "plot(AX,...)" plots into the axes with handle AX. Thank you.


@ Dear Simon,
Thank you so much. It's working now. I am new in Matlab. I have one more question. I have 10 plots in a figure. When I was trying to use column legend in my code for example

columnlegend(2, 'a', 'b', 'c', 'd', 'e', 'f', ‘g’,’h’,’i’,’j’, 'location', 'northeastoutside')

It shows just first legend in the graph.

Can you please help me to solve this problem?

Simon Henin


Your script cannot find the function. Place columnlegend.m somewhere in your MATLAB path (e.g. in same folder as script)


I am using R2016b. When I try to use this command it shows error
Undefined function or variable 'columnlegend'.

Error in untitled (line 4)
columnlegend(2, cellstr(num2str([1:numlines]')), 'location', 'northeastoutside');

Can anyone help me regarding this issue?

Thomas Debarre

Hi Simon,
Thanks a lot for this code! I've had one issue with it though: when using fplot instead of plot, object_h only has numlines elements, and so your code crashes. Not sure many people use fplot, but just letting you know.

Dear Simon,

Well, I figured out the mistake, so need to worry here. I forgot {'object1,object2} - the clams around the objects. Stupidy when working in MATLAB at 22:00 :D

It was awesome, thank you!

Best Regards,

Simon Henin


Use drawnow before changing the interpreter to make sure everything has finished rendering:

plot(rand(100, 4)); [legend_h,object_h]=columnlegend(2, {'h_1' 'h_2' 'h_3' 'h_4'});
set(findall(object_h, 'type', 'text'), 'interpreter', 'none')

Janine Teubner

Dear Simon,
how can I set the Interpreter to 'none'? Whatever I do, I cannot seem to disable the tex interpreter.
The reason behind that is that I have legend entries with underscores "_" which are interpreted as subscripts.

The typical way does not work: set(legend_h,'Interpreter', 'none')
I do not know why. The other way does work: legend(str,'Interpreter', 'none')
But then your code does not work.

Thanks in advance and thanks for the function.

Simon Henin


This seems to be a bug with MATLAB's builtin legend function. When returning handles, it removes any alpha formatting.

For example, try (the second legend call will not render the alpha transparency):
figure; plot(1:10, rand(10, 5), 'color', [1 0 0 0.1]); legend( {'1', '2', '3', '4', '5'});


figure; plot(1:10, rand(10, 5), 'color', [1 0 0 0.1]); [a,b,c]=legend( {'1', '2', '3', '4', '5'});

I will work on a workaround in the function for the next release. For now, here's a quick hack if you are using a common alpha value:

% make a plot with alpha lines
alpha = 0.1;
figure; plot(1:10, rand(10, 5), 'color', [1 0 0 alpha]);
[legend_h,object_h]=legend( {'1', '2', '3', '4', '5'});

% use the legend handles, and apply alpha to line objects
bb = findall(object_h, 'type', 'line');
for i=1:length(bb), set(bb(i), 'color', [bb(i).Color alpha]); end


Hi, this code is great, but I just wondered if there was a way of putting partly transparent colours in the legend. In my bar chart I have some bars of a certain colour, and some of the same colour, but with 'FaceAlpha' at 0.5, so they are partially transparent. In the legend, both of these appear as the full colour, is there any way to remedy this?


Simon Henin


Just like you would with the built-in legend command, like:
% plot 4 line
plot(rand(100, 4));
% add legend with custom labels
columnlegend(2, {'x','4','g','6'});

Linda de Man

how so you get your own input arguments so that in de legend it doesn`t display: 1,2,3, 4,5...... but someting like x,4,g,6

Simon Henin


You just need to pass the handles of the line objects you would like to use in the legend. e.g.:

% plot 8 different lines and return the handles
h = plot(rand(100, 8));
% add columnlegend and provide the handles of line objects 5-8
columnlegend(2, h(5:8));

Jamesa Stokes

Hi! This is awesome! One quick question: does this have the functionality to skip legend entries? If I have, for example, 8 lines plotted, but I only want to have legend entries/symbols for the last four lines?

Joshua Hajicek


For those who are interested in getting Latex interpreter for the Legend. Change the line

[legend_h,object_h,plot_h,text_strings] = legend(str);


[legend_h,object_h,plot_h,text_strings] = legend(str,'interpreter','latex','FontSize',12);

and put $$ at appropriate locations when making the call, e.g.,

columnlegend(2, {'$f(z)$'}, 'location', 'northeast');



Thank you for sharing this code.
I think I found a tiny bug though.
In line 41, the steps in the for loop shouldn't be 1 instead of 2? The 2 jumps are included in the cases when needed.
The 'boxon' and 'boxoff' doesn't require the step to be 2, for example.

Also, any tips on how to include a latex interpreter for the legends?



Thank you for sharing the code

Jiangpeng Cui

Jiangpeng Cui

Thanks for the nice code.
I want to put the legend in the southwest, can you list the objects of legend like this:

9 10
5 6 7 8
1 2 3 4

better li

There is error in line 138,' There is no ydata property on the Group class', there is scatter and plot in my figure

Crystal Hovland

Hi Simon,

I can't seem to find your function anywhere on File Exchange. Is there somewhere other than this page where it can be located?

Thanks, Chov

Gavin Osterhoudt

The function does not appear to be compatible with figures produced using scatter.

Sarah Pasternak

Thanks for this code!

Small bug fix:
current code only accepts locations where 'south' is in lower case, unlike "legend" command which is case insensitive.
To correct change line 171 from "if strfind(location, 'south')," to "if strfind(lower(location), 'south'),"

Yimao Sun

Thanks for your work. But there are some unknown reason make it doesn't work well in Matlab 2017. Location and box setting do not work.
Thank you.


Is there a way to control the horizontal spacing between columns ?

Stephanie Wells

Perfect. Just what I needed thanks.


@Simon Henin
It's a very usefull code,thank you very much.
but I found it doesn't work when i choose 'hist' of bar, why? follow is a example in Matlab 2017a:
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];

Andrew Macfarlane

Good code. To make the legend more condensed I reduce the line length and text space using a somewhat crude method:
Line 98: line_width = (xdata(2)-xdata(1))*rescale/L_R; % rescaled linewidth to match original
Line 99: spacer = xdata(1)*rescale/L_R;
% reduce the line and spacer by L_R=2.7

%Reduce space between columns St_R=1.6

Line 45: set(object_h(linenum), 'xdata', [col/numcolumns/St_R+spacer col/numcolumns/St_R+spacer+line_width]);

set(object_h(linenum+1), 'ydata', [height-(position-1)*sheight height-(position-1)*sheight]);
set(object_h(linenum+1), 'xdata', [col/numcolumns/St_R+spacer*3.5 col/numcolumns/St_R+spacer*3.5]);

set(object_h(labelnum), 'position', [col/numcolumns/St_R+spacer*2+line_width height-(position-1)*sheight]);

%Changed St_R and L_R to suit



I am trying the function R2015b. I get the following error:

Error using
There is no vertices property on the Group class.

Error in columnlegend (line 97)
vertices_1 = get(child, 'vertices');

Is there a solution to this issue?


It's a great program, but how to change the front size?

Akhil Karazhma

Daniel Tweed

Hi, works great but is it possible to set the number of rows per column? As in, if I have 13 entries and want 3 columns of 4,4, and 5 rows?

Daniel Tweed

Palash Sinha

Thanks a lot..this one is easy to use.....

ONE PROBLEM, When saving figure using savefig('filename.fig'), the columns are merging into one ! Looking for solution....


Thank you for this great function. I want to know that is there anyway to change the background color of the legend. Thanks.

Anton Kuznetcov

Hi Simon, thank you very much for the function. I am experiencing one issue, though. If I change the font size using the method below, it will be reset to the default when I try to move the objects in the figure manually. Do you have any ideas how to deal with that? Thanks.

Simon Henin

Take a look at conversation with Qasim from June 5th. That should solve your problem.

Roger Hill

I like this it works really well apart from I can't set the size of the legend font. Is there anyway to do this? Or add it into the code as a argument?

Simon Henin

Actually got inspired to quickly add an extra option to the function, namely a "padding" option which adds additional space (in normalized units e.g. 1 = 100% additional padding) between legend entries. So something like:

r = rand(10,5);
[h,objs]=columnlegend(2, {'h_1', 'h_2', 'h_3', 'h_4', 'h_5'}, 'location', 'southeast', 'padding', 1);

Let me know if that helps!

Qasim Manzoor

Thanks for the fast reply. I got the same effect by adding the fontname attribute (\{times new roman}) to the string cell that I feed to columnlegend. Also changed the font to a larger number which causes the legend lines to overlap if placed southeast or southwest. Was wondering how i could add more space between the different legend rows. If i can solve that then everything works perfectly. Thanks for the function.

Simon Henin


Sure. You just need to format the returned text objects:

[h,objs]=columnlegend(2, {'h_1', 'h_2', 'h_3', 'h_4', 'h_5'}, 'location', 'northeastoutside');
drawnow; % make sure everything is finished rendering
set(findall(objs, 'type', 'text'), 'fontsize', 18, 'interpreter', 'tex')

Qasim Manzoor

Is there any way to change interpreter to latex? also font size for the legend entries?

Gustavo Rodrigues

Hi, Unfortunately it's not working here. That's the error message I get:

Attempted to access vertices_1(2,2); index out of bounds because

Error in ==> columnlegend at 92
sheight = vertices_1(2,2)-vertices_1(1,2);

Error in ==> Comparando_Massas_m at 39


This is a great function but unfortunately it does not support patches:
>> h=patch('FaceColor',[1 0 0],'EdgeColor','black');
>> columnlegend(h,1,'TEST', 'location', 'northeast','boxoff');

Is this something that could be added in the future?
Thanks a lot!

Simon Henin

@Kevin Delaney

This seems to be a bug in R2016b, which I cannot seem to resolve. It does not happen in previous releases (R2016a) or in the latest (R2017a) Release. My suggestion is to upgrade or downgrade if you would like to use this function.

Kevin J. Delaney

This is a great function; I use it all the time and it makes plots look more professional.

But I'm getting errors with R2016b if I resize axes containing a columnlegend:

Struct contents reference from a non-struct array object.
Error in>doUpdateCompatible
Error in
Error in

Anyone have a workaround? I've submitted a bug report to MathWorks but they say it's "third-party software" and therefore not their problem.



My legend entries have multiple lines (newline characters within the string), but using this only allocates one line per entry. Is there a way to change this?



Wagih Abu Rowin

You can change the font size and type by using this easy code:

leg_str={'\fontname{Times New Roman}\fontsize{13} data 1','\fontname{Times New Roman}\fontsize{13} data2')

h = columnlegend(2,leg_str);


Hi Simon,
Many thanks for your quick reply. It solves my issue.

Simon Henin

@A. The "Best" locations are not yet implemented in this version. However, you can use any of the traditional outside locations (e.g. Southoutside, Northeastoutside).


Is it possible to place the legend outside of the plot using columnlegend? An example
subplot(211) % Reference plot
legend('Test1', 'Test2','location','bestoutside');
subplot(212); % Test plot
columnlegend(2, {'Test1', 'Test2'},'location','bestoutside');

Hyunseong Min


Simon Henin


Good catch. I will add this as an option in a future update. For now here is a simple work around:

figure; plot(rand(100,2)); [~,h]=columnlegend(2, {'test_1', 'test_2'});
set(findall(h,'type', 'text'), 'interpreter', 'none'); % change the interpreter on all text objects with the legend object


Hi Simon,

Congrats on this awesome function, however the Interpreter cannot be switched off which leads to annoying legend display when using underscores.


dhaba india

Simon Henin


The function does not work with bar graphs at the moment.

Claire Harnett


I keep getting the following error :

Error using
There is no xdata property on the Group class.

Error in columnlegend (line 72)
xdata = get(object_h(numlines+1), 'xdata')

I am trying to split a bar chart legend into columns. Does anyone have any advice? Thanks.


Simon Henin


Updated 'southoutside' location option



Hi Simon, I encountered a small problem when specifying the legend location to be "southoutside": the legends are too close to the x axis and hence overlap with the x ticks in date format. I don't have this problem when using the "legend" command.

Simon Henin

Just uploaded a new version with new legend positions, including outside legends.

Patrick Ziegler

does not work for outside legends...

Jan Cerny

I have trouble with input argument. I am using MatlabR2012b and I am keep getting the error: Undefined function 'columnlegend' for input arguments of type 'cell'.
Even if I run the example code.I got this error :(, any suggestion anyone?

Alberto Greco


Hello Mikkel Gryning
Somehow, the code change fontsize back to 9 no matter what number I put in the input.


Hello Mikkel Gryning
Your way doesn't change at all. I am using 2016a


The wat to set fontsize is not working. It changes the size of the box but the fontsize remains the same.
I am using 2016a

Simon Henin


you could try something like this:

leg_str={'\fontname{WingDings} Text A','Text B','Text C'};
h = columnlegend(3,leg_str);

Obviously, change to a system supported font and apply to all legend entries.

Pádraig Daly

Hi Simon,

Is there any way of setting the FontName? It doesn't seem to work for me:

leg_str={'Text A','Text B','Text C'};
h = columnlegend(3,leg_str);
set(h,'position',[0.15,0.85,0.75,0.1],'FontName','Times New Roman')


Cannot place the legend southoutside

Erkan Polat

when i save the image as Matlab figure and reopened it, the column format disappears.


Great function. For people that would like to use the 'NorthOutside' location, just add the following code in switch lower(location) (i.e. at line 124):
case {'northoutside'}
set(legend_h, 'position', [pos(1) pos(2)+pos(4) pos(3) 0.05]);


Could you make the legend movable when dragging?
Thank you.

Andrea Libri

Simon Henin


Sure, you could try applying the style after creating the legend. For example:

>> plot(rand(10,3)); h=columnlegend(2, {'1' '2' '3'});
>> set(h,'box', 'on', 'color',[1 0 0])

Christoph Hachmann

Hi Simon,

Is there a way to change the background colour of the legend box?

Simon Henin

@Daniel, @Mikkel
Thanks for your feedback. I have updated the submission to add this capability and make it compatible with 2015b

Mikkel Gryning

As an extension to the comment by Daniel (01/09/2015), this does not work for me in 2015a.

If you as he suggests adds:

case 'fontsize'
fsize = varargin{i+1};

To the switch loop, but adds,

%create the legend
[legend_h,object_h,plot_h,text_strings] = legend(str);

It works for me. They must have changed the access pattern in 2015.

Hope that it helps someone :)



Some posts have asked about font size adaptation, and I have also required this. I added a simple workaround (which is a bit bodged, but works for my purposes). You can add a search condition in the first switch loop :

case 'fontsize'
fsize = varargin{i+1};

Then you can set your fontsize after the basis legend is contructed:

%create the legend
[legend_h,object_h,plot_h,text_strings] = legend(str);

You can call the modified function as normal with the additional fontsize spec:



Wenwen Li


I call this function as columnlegend(2,legendNames,'Location','NorthWest'); However, I got an error as follows.

Error using hg.hggroup/get
The name 'xdata' is not an accessible property for an instance of class 'hggroup'.

Any clue?


Sébastien Martin

Good job for creating the layout.

Some modifications can be made to handle scatter plots, which consist of only one element in legend (linenum = linenum+1;)
I haven't tried with other types of plots


very good!

Alceu Costa

Very useful and simple to use.

Tamara Schapitz

This works out great! The only thing I would like to change is, that the legend can also be located outside the diagram (e.g. 'southwestoutside')

The only possible values at the moment are: 'NorthWest', 'NorthEast', 'SouthEast', 'SouthWest'
Could somebody help me, at which point I would have to adapt the code?

jun jun

Thomas van Dijk

Dear reader,

I tried to plot the exact code as you wrote it but get the error: Undefined function 'columnlegend' for input arguments of type 'cell'.

Error in test (line 9)
columnlegend(3, legend_str, 'Location', 'NorthWest', 'boxon');

Does anyone have a suggestion what it might be?


This is a great tool for relatively simple needs, but I found immediately that I can't do much additional legend customization. Just doing
set(lh,'fontsize',8) caused my legend to revert to a single column. Could you include more input options or perhaps make the legend in a way that changing other properties won't affect the layout?


That's great! Thank you very much.
I wish it also support 'Best' location like the legend of Matlab.


It works very fine with me, I highly recommend to use export_fig to print the plots. I think that it will be a nice improvement if we can pick a 'North' location for example, 'cause if you need to put in the middle of the figure you must move the legend with get 'Position' and set 'Position'. Best Regards Simon.


@Aslak Grinsted
I you want to give it a vector of handles like you can do in the legend function, its a small change in columnlegend.m
first give it a extra input, e.g. 'hdl' in line 1:

function legend_h,object_h,plot_h,text_strings] = columnlegend(numcolumns, hdl, str, varargin)

and then change line 49 as well to:

[legend_h,object_h,plot_h,text_strings] = legend(hdl,str);


Hey there,

I revisited this function today after writing a script to make some custom bar graphs. Anyways, I tried running this function to make a 2-column legend, but hit an error. I then ran the simply code you provided above, and hit the same error, which is:

Error using hg.hggroup/get
The name 'xdata' is not an accessible property for an instance of class 'hggroup'.
Error in columnlegend (line 61)
xdata = get(object_h(numlines+1), 'xdata')

I may try fiddling some more tomorrow, but this is only a matter of convenience to make the plot prettier, so if there isn't a simple fix I'm missing no worries about responding.


Simon Henin


As you know, this error is a general MATLAB error when it cannot find the function in its path. The reason why it is 'double' is because the first argument of columnlegend is a figure handle cast as a double.



I know from trial-and-error that this error just has to do with pointing to the right folder in matlab, but it just isn't clear exactly what this has to do with the double format. I know double has to do with exactly how the info is being saved or read by matlab, but it's still mysterious to me exactly what double is or at least when/why this format is needed.


Actually, this is my error:
"Undefined function 'columnlegend' for input arguments of type 'double'. :

It's not clear to me what makes the input argument('leg_str') a double type of variable. I tried num2str(leg_str) as well.


New to matlab here, but this function will be very convenient for me to use. I get the following error whether I copy/past your code here, or call the function using my own str:

Undefined function 'columnlegend' for input arguments of type 'cell'.

Sebastien Corner

I forgot, you ll have to go also to the print function, highlight print and ctrl+D and comment line 293
% pj = restore( pj, h );

Sebastien Corner

For those who has a problem with printing when changing the legend, I find a solution.
insert this after legend is created inside the function columnlegend

pt = getprinttemplate(gcf);
cd('C:\Program Files\MATLAB\R2012a\toolbox\matlab\graphics\private')

and copy past the legend command

lin0 is your main directory.
Also you may want to run Matlab as Administrator.
The raison the legend is modifyind when printing is because print function will set the front weight , name, of your text inside the legend. If this is modify the legend come back to its original position.
try this
set(legend_h1,'FontName', 'Helvetica')
you will see the legend will reset.
I modify the function also such that I create the legend in my script and insert it as a parameter inside the function . I inserted the 3 lines solution between the creation of the plot and my call for columnfunction.
If you have any pb I ll be happy to help

Simon Henin

@ Mik

Thanks for your comment. Not included in the documentation is the fact that the function returns the legend's object handles. Therefore, you could alter these properties on your own.

Something like this would do it:

[legend_h,object_h,plot_h,text_strings] = columnlegend(...);

set(legend_h,'box','on', ...
'color','y', ...
'ycolor','m', ...
'xcolor','b', ...

Mik Mønsted

Hey. Very nice function. Just what i needed.
Is there any way to make it non-transparent? My graphs are making the text somewhat illegible.

Wasim Malik

I'm getting this error (using Matlab R2013a):

Error using hg.hggroup/get
The name 'xdata' is not an accessible property for an instance of class 'hggroup'.

Error in columnlegend (line 61)
xdata = get(object_h(numlines+1), 'xdata');

Any clues? Thanks!

Lukas Halagacka

Hi, very nice part of code! But the columns of legend are put together ones the .eps figure is printed. Do you have any idea how to fix it?


Thomine Stolberg-Rohr

Ligong Han

very useful


I want to change the fontsize of the legend to 14, is that possible?
The text is to small to see in a document, the way it is.


I found a bug of this program. For example, when you try to change 1_by_2 legends to 2_by_1, this program will not work. Because the numpercolumn is 1, and the col is always -1.

Replace the code

if mod(i,numpercolumn)==1,
col = col+1;


if numpercolumn>1,
if mod(i,numpercolumn)==1,
col = col+1;

to kill this bug.


Durga Lal Shrestha

The columnlegend hides the box around the legend as it is not possible to force the box to be smaller than the
original height. The work around to display box is to use annotation.

The following code can be added at the very end of "columnlegend" to show the box around legend:

pos = get(legend_h, 'position');
orgHeight =pos(4);
pos(4) = orgHeight/numlines*numpercolumn;
pos(2)=pos(2)+ orgHeight-pos(4);

Hi Simon,

I mixed line plots and scatter plots, what a pitty.

Anyhow, the function is great.



Simon Henin

@ Javier

Unfortunately, at this time this script only works for line graphs, such as created via the plot command. You were probably trying to use the script on a bar or other non-typical matlab figure object.



I am having a problem with one of my graphs:

??? Error using ==> get
There is no 'xdata' property in the 'hggroup' class.

Error in ==> columnlegend at 42
xdata = get(object_h(numlines+1), 'xdata');

I dunno the reason. The function works with the example on

Sturla Kvamsdal

Update: The problems probably has nothing to do with subplots (tried it in a simple example). Error message:
??? Index exceeds matrix dimensions.

Error in ==> columnlegend at 77
set(object_h(linenum), 'ydata', [(height-(position-1)*sheight)

Sturla Kvamsdal

Brilliant, just what I need. Have problems with subplots, though.

Simon Henin


Please refer to the full file description. To export to vector graphics files, use an advanced figure export (I recommend export_fig,

not compatible with eps format.
So not useful to generate figures to be included in latex documents....

Aslak Grinsted

Nice, useful and compact code! It would be nice if i could give it a list of handles to put in the legend.

Simon Henin

Thanks for the comment, this has been fixed.


Nice, but doesn't work if you have used markers.

Martyn Dorey


MATLAB Release Compatibility
Created with R2008b
Compatible with any release
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

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

Start Hunting!