Code covered by the BSD License  

Highlights from


4.8 | 39 ratings Rate this file 122 Downloads (last 30 days) File Size: 1.05 MB File ID: #20003
image thumbnail




21 May 2008 (Updated )

Like subplot, but easier, and WYSIWYG export to file. Also fixes dashed/dotted lines in export.

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

| Watch this File

File Information

Panel is an alternative to Matlab's "subplot", providing easier control over layout (particularly, easy elimination of whitespace). It also fixes dashed/dotted lines during export to image files (both vector and bitmap formats).

If you find the layouts generated by subplot() have too much space and not enough axis, try Panel. If you find it tedious to construct subplot layouts that are more complex than a simple grid, try Panel. If you always resort to other software to prepare your final figures for publication because you can't get the appearance you want from Matlab, try Panel.

Panel was designed to produce output for print publications directly from Matlab. Layouts are, by default, in physical units (mm, by default), and exporting to a graphics file targets print columns directly. However, it performs equally well if the end goal is digital display, providing easy control over use of screen real estate.

Panel incorporates features suggested by several Matlab Central users, as well as some code - see the documentation for details.

Questions? Please see the first.


This file inspired Block Edf Heat Map View.

MATLAB release MATLAB 7.10 (R2010a)
Other requirements Requires a version of Matlab that supports the "classdef" syntax. I understand that means R2008a or higher.
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (150)
16 Oct 2014 Ben Mitch

Hi Max - margins are respected between panels within their parent and between the root panel and the edges of the canvas (figure or image file) - see doc panel/margin.

Hence, if you set a zero margin for "p", you'll see your child axes butt right up against the figure edge. Their own margins are not respected versus the figure edge.


16 Oct 2014 Maximilien Chaumon

Thanks for your tool.
I'm trying to test it and have a problem, which I think boils down to the following:

p.margin = [0 0 0 0];
p.pack('v',{.35 []});
p(1).margin = [20 20 20 20];

Which returns:
Parent root: [attached to Figure 27, vert] [ margin 0 0 0 0 mm]
Parent (1): [0.350, hori] [ margin 20 20 20 20 mm]
Object (1,1): [0.400] [ margin 20 20 20 20 mm]
Uncommitted (1,2): [stretch] [ margin 20 20 20 20 mm]
Uncommitted (2): [stretch] [ margin 0 0 0 0 mm]

Why is it that although I set the margins to 20 mm on all sides in p(1) (and I see it in the printed result), it won't show it on the displayed axes ?

Many thanks for your help.

03 Oct 2014 Ben Mitch

Hi Andrea

Sounds like you may be being tripped up by the fact that "colormap" is a property of a figure, not an axis. This is not related to panel.

I can't grok the code you posted, but the way out of this problem is usually to use RGB images rather than indexed images. If you plot "image(rand(30,30,3))" you will notice that the resulting image does not change if you change the colormap.


02 Oct 2014 Andrea

Hi! First, english is not my language, if you have problem to understand me, please, don't worry, you can advise me.
I love your panel.m, but i have problem to manage some function.
I have to plot several graphic, and each graphic use pcolor. The problem is linked to the fact that the final cmap will be extend to the other graphic, what can i do to avoid this problem?

This is my code:
p=panel();%Creoil pannello
% p.title(p,['Time = ', num2str(Time/1e6/365.25/86400),' Ma'])
%Creo due svbvanneli, il primo contenente i P-T-t, il secondo Vis, viz
p.pack('v',[1/2 1/2] )


for j=1:num_points
T=markt';% Per visualizzare i dati in modo più liscio, è necessario usare fnplt2 in associazione con cscvn, per utilizzare quest'ultima è necessario trasporre i dati di P-T-t
%if i<=5
fnplt2(cscvn([T(j,1:i); P(j,1:i)]),fmap(j,:),2.0);
axis ([0 700 0 10])
xlabel ('Temperature')
ylabel ('Pressure')
title ('P-T-t path')

hold all


%% Compos1zione

% if temp
% [c,h]=contour(x_vec_t,z_vec_t,ColorGrid_t,100:200:2300,'r','LineWidth',0.5);
% end

shading interp
if spec == 'c'
caxis ([0 99])
if cmod
caxis ([cmin cmax])

axis ij image

hold all


% x=markx(q,2);
% z=marky(q,2);



hold off

if temp1
hold on
axis ij image
hold off

xlabel('X Width in km')
ylabel('Z Depth in km')
title(['Time = ',num2str(Time/1e6/365.25/86400),' Ma'])


%% Viz
% plotting


if temp
if logmod
for m=1:ynum
for n=1:xnum
if abs(vizmat (m,n)) < 1
vizmat (m,n)=0;
vizmat (m,n)= sign(vizmat(m,n))*log10(abs(vizmat(m,n)));
vizmat = sign(vizmat).*log10(abs(vizmat));
shading interp
if cmod
caxis([cmin cmax])
axis ij image
axis([gx(1) gx(end) gy(1) gy(end)])

I'm principiant... i know, i hope you will give me an answer, have a nice day, see you

10 May 2014 Gautam Dey  
02 May 2014 Ben Mitch

If a function does not return a handle, you can usually recover it by walking the figure tree - start with get(gcf, 'children'), and work from there. Not elegant, but...

02 May 2014 Ian

Thanks for the ideas Ben, not all the functions return handles :-(, but for those that do your idea is that I let the external function create the axes "free", then set up my panels, then use .select(axis_handle) to capture the axis into the correct panel -- I hadn't thought of it that way as I normally always select() before I plot. Will give this a go when I get time. Thanks again for a such a useful utility!!!

p.s. and yes the various website bugs on FEX are annoying, I normally copy my text before submitting just in case here...

01 May 2014 Ben Mitch

Oh, and brilliant. I've come a cropper by this website's daft bug of eating your 1st post if you post twice. Again. I wish they'd fix that.

I'll not post it all again, the essence of it was:

1) I could imagine adding a flag to panel so that it would respect the existing layout of some set of select()ed objects, and reflect it when it does layout. However, I'd implement it by creating child panels with absolute positioning, so...

2) Why is what you are wanting to do difficult to do using absolute positioning, applied manually, thus?

% axis handles from toolbox X
h1 = ...; h2 = ...;

% pack into a panel
p.pack({[0 0 1 0.45], [0 0.55 1 0.45]};


01 May 2014 Ben Mitch

Oh, it just strikes me, this isn't a misunderstanding is it? I mean, obviously panel lives and breathes "non-overlapping". This situation is different, right? Sorry, just realised that I can read your original post in more than one way.


01 May 2014 Ian

My problem is that I have a several functions from a large toolbox that plots 2 axes, one above the other into a figure. I need to use their function *unaltered*, but want the output (2 axes, non overlapping) into 1 panel (relatively positioned). Whenever I select() or resize, panel then sets the positions of both *axes* within the panel to the same values (overlapping). If I could rewrite their functions I could use panel for layout but I'm trying to avoid shadowing lots of code in their toolbox... I think select() always calls recomputeLayout() which assumes the child axes should fill the panel (as in demopanelG). Cheers!

30 Apr 2014 Ben Mitch

Hi - as often happens, the site has stopped sending me notifys when people comment, so I've not seen these comments, sorry. Thankyou for the nice feedback.

@Ian - If they are non-overlapping, I suggest you use absolute positioning instead, see demopanel6. Is that what you need?


18 Mar 2014 Ian

Hi Ben, another feature request: In demopanelG you show two axes being passed into select(). At the moment these axes have the same 'Position' property. Often one may want to position an axis over another, and using select() on these loses the position of each axes, forcing them to overlap. It would be great if we could pass in axes to be managed by a panel that may have non-overlapping positions.

17 Mar 2014 Jim

Amazing work Ben, thank you for sharing. Tried many other approaches for altering how Matlab displays plots and yours is certainly the most exhaustive and well thought out. Allowed me display my data exactly how I wanted, saved me a lot of time!

29 Jan 2014 Ratman

Hi Mitch, cheese!

10 Dec 2013 Henrik  
06 Dec 2013 Joel

Works like a charm, thanks!

05 Dec 2013 Ben Mitch

Hi Joel, thanks for the comments.

In answer, I don't generally use panel like that (rather, I mod the script and run it from scratch again), but it can be done if you prefer messing around at the command line. As I say, this is relatively untested because I don't use it, so ymmv.

I think if you delete a child panel, everything behaves, and you can call delete on an array of panels. So, in your example, try:

delete(p(1).children); % p(1).reset()
p(1).pack(2, 2);


05 Dec 2013 Joel

Hi Ben!
I'm wondering if there is a way to reset a panel.
Something that works like this:

p = panel;
plot([1 2], [1 2])



22 Oct 2013 Anna

Thanks, working great now. Thanks for your help and thanks again for such a helpful tool!

21 Oct 2013 Ben Mitch

Hi Anna, thanks for your comments :).

"annotation" is adamant throughout its help that it works in "normalized figure units" so I would have thought that's that. except, if you create one, and then change its "parent" property to an axis, lo and behold it becomes locked to the axis rather than the figure. out of date docs? perhaps. a google on "matlab annotation axis" turns up this solution elsewhere, too, btw.

h = annotation(...);
set(h, 'parent', gca);

in the interests of full disclosure, your workaround could be made to work with panel (were it still necessary). the way to do it would be to get panel to notify you when the layout is changed. do:

p.setCallback(@myfunc, 'mydata');

and the function "myfunc" will get a call every time the layout changes under "p". this is what I'd have suggested if the axis/parent solution hadn't worked.


21 Oct 2013 Anna

Hi, thanks for a great tool! A quick newbie Q... I'm having trouble adding a custom legend to one of my panels. Positioning text labels is easy using 'unit' 'normalized' to position within the current panel. But 'annotation' (for adding lines, box etc) seems to only position things with reference to the entire figure window. Am I missing something? I've tried a workaround using p(1,1).select(); axesPosition = get(gca, 'Position'); but it's not ideal because of subsequent changes to panel positions in my code. Is there a way to reference both text and annotation positions to the current panel (either data units or normalised to axes?). Any advice would be appreciated!

10 Sep 2013 Fedor

Thanks for a very useful tool!

04 Sep 2013 Kazumasa

thanks Ben, how fast you get an idea to implement the suggestion! Then I'll look forward to the future release. Thanks again!

03 Sep 2013 Ben Mitch

hi Kazumasa

thanks for your comments. save panel management with figure... is a great idea. you'd have to walk the graphics object tree and store associations as references rather than handles, then reassociate on load. little bit of work in there, so I can't do it immediately, but I'll put it on the to-do list for the next version. thanks for the suggestion :).


03 Sep 2013 Kazumasa

Hello Ben,

thanks a lot for the great contribution!

I'm wondering if there is a way to save a panel-managed figure with the associated panel variable, so that I can load the figure later and handle it by the panel functions. If it's possible, panel will be really something indispensable to me..!

28 Aug 2013 Ben Mitch

hi Frank

I can't fathom how that would be related to the problem you outlined, and panel works fine with the latex interpreter, afaik. but there you go, computers are like that sometimes - glad you got it sorted, anyway :).


28 Aug 2013 Frank

hi Ben,
I have finally found the mistake.
In a different figure I have

and panel does not seem to like that.
As soon as I declare tex as default it all works. Thanks again.

28 Aug 2013 Ben Mitch

hi Frank

your revised code works fine here (R2011b/win64), so it seems that the problem is either specific to your environment or to your matlab version. which version/OS are you using?

I don't know what "produces one empty bar graph" means, I'm afraid. where in the figure? what does "empty" mean? one possibility is that the first axis is getting destroyed when you create the second. another is that the first axis is ending up with the second bar3 in it. could you post a figure?

in any case, the two functions bar/bar3 should produce the same gross behaviour, so either there's a bug in the version you have, or - and this is always worth checking - you are using a non-standard bar or bar3. check the output of "which bar" and "which bar3": they should both be under "specgraph". what is probably happening - for whatever reason - is some confusion over the "current axis". sprinkle the gca command around to find out what's going on.


28 Aug 2013 Frank

Hi Ben, thanks for the answer.

What I mean is that my code

p = panel;

produces one empty bar graph, while

p = panel;

correctly produces one bar3 and one bar graph.

27 Aug 2013 Ben Mitch

hi Frank

your code line "p = p.pack(1,3)" does not work, I've changed it for "p = panel; p.pack(1,3)". with that change, your code works fine here.

you said it "fail"s for you, but you don't say how.


27 Aug 2013 Frank

I want several 3D bar graphs is my plot but can't get it to work. An example is below.
If I replace the second bar3(a) with plot(a) or even bar(a), then it produces proper output.
But any graph containing bar3 twice seems to fail and I don't understand why.


22 Aug 2013 Ben Mitch

hi Jerry

yeah, I suppose it could do something like try and squeeze things in by default, but it doesn't do anything like that at the moment. perhaps version 3 :).

incidentally - you know that the msg is only a warning, not an error. if you maximize the window, the panels will probably get rendered correctly. certainly they will if you adjust the margin. it just means "can't render the panel under the current conditions".


22 Aug 2013 Jerry Gregoire

If the default margin is not changed and too many plots are requested then it issues: Warning: a panel had zero size, and the managed object was hidden. It should accommodate with smaller subplots like subplot does.
Here is an example:

%Works - >
p = panel();
p.pack('h', {0.50, 0.50});
p(2).pack({0.50 []})

% Change p(2,1) -> Will not work
p = panel();
p.pack('h', {0.50, 0.50});
p(2).pack({0.50 []})

% Change default margin -> Works again
p = panel();
p.pack('h', {0.50, 0.50});
p(2).pack({0.50 []})
p(2,2).pack(2,2) = 1;'all')

Other than that gotcha, I like it.

07 Aug 2013 Ben Mitch

Hi - thanks for posting that info. I guess that function appeared in a later version.


07 Aug 2013 J

I was able to find the source for isrow() on the matlab central file exchange. Just google it and the matlab central file exchange. Then save it as a new function in a your path.

07 Aug 2013 J

I am using MATLAB 7.10.0 (R2010a), and I am getting this error: Undefined function or method 'isrow' for input arguments of type 'cell'

Is there anyway to fix this?

26 Jul 2013 Ben Mitch

Hi Opher

Thanks for your comments. This is because "margin" is an inherited property, so all subplots will get the value you have chosen. See demopanel9 for a well commented example of how to set margins.

In any case, what you want is something like:

% default margin everywhere
p.fa.margin = 2;

% specific root margin
p.margin = [5 5 15 15];

% other specific margins


26 Jul 2013 Opher Donchin

Thanks for this. It seems very throughly thought through.

One question: when I use margin on the root:

p = panel();
p.margin = [5 5 15 15];

I get an effect on the subplots instead of on the root. How do I get an effect on the root?

14 Jun 2013 Jaekyun

Nice work and demos :)

29 May 2013 Muthu Annamalai

Nice looking panels.

24 May 2013 Alex  
16 May 2013 Iman Ansari  
11 May 2013 Ben Mitch

Release 2.10 will appear shortly. This release is significant, since the optimisation approach to layout has been replaced by a procedural approach. This should mean no more poor performance for users without the optimisation toolbox (Per Nordlöw, I hope this helps you at least :D). The 'defer' flag should now be obsolete (it will continue to be supported).

This release also adds support for panels of fixed physical size, which obviates the need for the inelegant workaround suggested in the comments below. see the new "help panel/pack" for details. This has led to a change of recommended syntax to the pack() function, as follows:

OLD: p.pack([0.2 0.3 -1])
NEW: p.pack({0.2 0.3 []})

The old syntax is still supported, and there are no plans to withdraw support, but new code should use the new syntax (swap -1 for [], and [] for {}). To pack a panel of fixed physical size, simply enclose your size in a cell array, for example:

p.pack({0.2 {50} []})

NB: This is a fairly major rework - mission critical users (ha!) might stick with 2.9 until June, in case of any issues.

10 May 2013 Ben Mitch

PS. I've added this to a nascent FAQ, since it's been asked twice :)

10 May 2013 Ben Mitch

Hi Bahaa

Thanks for your comments. The workaround for semilogx() etc. is covered further down this page.


10 May 2013 Bahaa

Hi Ben,

this is an amazing work ... thank you for sharing.

I have one comment on it ... when using 'semilogx' or 'loglog' for plotting in the selected panel. the plot axis remains in linear scale... is there a way to change it to be in log scale.



03 May 2013 Ben Mitch

Release 2.9 will appear shortly. Only minor updates, no need to upgrade. Release log has details.

12 Apr 2013 Ben Mitch

Release 2.8 will appear shortly. panel.plot() is withdrawn, and replaced by panel.fixdash(), which simplifies use and improves performance. See demopanelI (the updated version) for suggested usage. It's pretty neat, now, actually, do please try it out and let me know what you think :).

29 Mar 2013 Ahmed A. Selman

Very nice function, elegantly written.

21 Mar 2013 Ben Mitch

Release 2.7 will appear shortly. It adds a demonstration of how to do inset plots (tx Ann Hickox), but more interestingly adds panel.plot(), an integrated function for plotting dashed and dotted lines that works around the poor rendering of these in bitmap exported images.

NB: In this release, setCallback() is renamed to addCallback(), to support the new plot() function - if you use setCallback() you will need to search/replace.

14 Mar 2013 Ben Mitch

hi Elliot

Firstly, the answer is inelegant, and it would be nice if Panel offered packing at a fixed size rather than only at relative size. Perhaps in a future version. However, you can work around as follows (and yes, the callback was the right idea). First, you'll have to edit panel.m itself to allow yourself access to the "packpos" property, add these lines:

case 'packpos'
out = p.packpos;

round about line 2289, just under case 'figure'. Restart Matlab. Now, the key features you need are:

1) attach the callback to "p", the root panel. this is a bit more intuitive, though you can achieve the same thing your way too.

2) access p in the callback through "p = data.panel". then you have p.figure, p(2).object (which is "u2"), get(p(2).object, 'children') (which is "tab"), etc.

Now, calculate the correct packing size for p(2), check if it's the current packing size (i.e. check if it's equal to p(2).packpos) and, if not, p(2).repack() it.

Phew, what a pain. Works, though. So yeah, one item on the to-do list for next version is to allow fixed size packing.

The full code is at and it's not something I'm proud of.


14 Mar 2013 Elliot

I'm having a little trouble setting up the layout I want, that includes a plot above and a data table below. The two main goals are:

1. Let the plot take up as much space as possible without cutting off any of the table
2. When the window is resized, resize the plot but leave the height of the table fixed.

Below is what I have so far, but I have to fudge the height of the table, and the resizing doesn't work because I don't know how to access the properties of my uipanel and uitable from inside a callback function.

Can anyone please provide some guidance?


% Create some data and a table
X = randn(100,3);
tableData = [mean(X,1); std(X,[],1)];

% Set up the figure
set(f, 'units', 'normalized');

% Create the uipanels
u1 = uipanel('units', 'normalized', 'position', [0 0 1 1], 'backgroundcolor', [1 1 1]);
u2 = uipanel();

% Create the uitable and get the relevant sizes
tab = uitable('Parent', u2, 'Data', tableData, 'units', 'normalized', 'position', [0 0 1 1]);
pos = get(u2, 'position');
ext = get(tab, 'extent');
set(u2, 'position', [pos(1:3) ext(4)]);

% Set up the panel
p = panel(u1);
p.margin = [5 5 5 5];

% Pack two subpanels, with the bottom panel's height fixed (to hold the
% uitable)
% Can I automatically account for the margins without having to add a
% buffer like this?
p.pack([-1 ext(4)+0.02]);

% Add the plot

% Add u2

% Get rid of the scrollbars
jtab = findjobj(tab);
set(jtab, 'VerticalScrollBarPolicy', 21);
set(jtab, 'HorizontalScrollBarPolicy', 31);

% If I set up a call back, how do I access the position of u2 and the
% extent of tab from the 'data' argument?

14 Feb 2013 Pio Nonus

Thanks. It works perfectly.

17 Jan 2013 Chris Betters  
10 Dec 2012 Ben Mitch

Hi Tim - thanks for the feedback :)

Yes, indeed, that will work, as will any of the other things you can do with figures (at least, I hope so). Panel should interact well with anything else you want to do with a figure, so please let me know if there are any compatibility problems.


10 Dec 2012 Tim

Ben - Great submission!
figure('units','normalized','outerposition',[0 0 1 1])
rather than the usual figure command makes the created figure full screen. Thanks.

14 Nov 2012 farhan  
29 Sep 2012 Ben Mitch

hi Kate - not sure, probably. I've not used copyobj before. If you figure it out, please send me a demo for the collection :)


24 Sep 2012 Kate

Is it possible to open a saved figure, then insert everything in that figure into a subplot of a Panel? Similar to what is possible using copyobj and subplot. I did not see a relevant demo, but perhaps I just missed it? Thanks for any pointers!

08 Aug 2012 Wyllian

Very powerfull tool. Suitable for graphics professionals.

25 Jul 2012 Ben Mitch

...and Release 2.6, now available, also adds export to SVG and includes a documentation update.

24 Jul 2012 Ben Mitch

info: the release on 23 Jul 2012 is unlabelled, but is Release 2.5.

23 Jul 2012 Ben Mitch

hi Kuo-Hsien

think you're probably trying to do this...? in terms of layout:

p = panel();
p(2).pack('h', 2);

that is - rather than including those scalar dimensions, use 'h' to switch to horizontal packing for the second pack command. the way you had it does work just fine, but it makes the references rather complex (e.g. p(2,1,1,1)). try'all'), p.identify(), to see what you've ended up with.

next, to make what is now p(2,1) packed at 2/3, you should change the last line to:

p(2).pack('h', [2/3 -1]);

note that -1 means "stretch to fit". see demopanel4 for a full example.

hope that helps
cheers, ben

22 Jul 2012 Kuo-Hsien

How to let p(2,1,1) occupy 2/3 of the area of p(2, 1).pack(1, 2) ??

Here is my code:
p = panel();
p.pack(2, 1);
p(2, 1).pack(1, 2);

20 Jul 2012 Ben Mitch

Brendan - see release 2.5 for management of multiple axes (see demopanelG).

Please note that this release (2.5) may, possibly, have bugs, after this rather significant change - please revert to 2.4 if you have problems, and report them here. Thanks :)

20 Jul 2012 Ben Mitch

Glad it's a help to you, Karl, thanks for the comments :)

20 Jul 2012 Karl

Great function. Super-useful-- I may never have to touch up another figure in Illustrator. Incredibly well documented, and the demos are invaluable.

20 Jul 2012 Karl  
17 Jul 2012 Ben Mitch


I've had a look through, and it looks like it will be possible to manage two or more axes per panel, no problem. However, it's going to take a little time to go through step by step and try not to make any bugs, so I'll have to do this another time. I will try and get to it next week.

cheers, ben

17 Jul 2012 Ben Mitch


I've tracked this down, now. Panel sets the "NextPlot" property of automatically created axes to "replacechildren", whereas the default is "replace". This is to protect modifications to axis labelling due to panel (i.e. fonts, i think). A side effect is that the high-level plotting functions semilogx/semilogy do not change the scale of the axis. It doesn't look like there's any way to control these things separately, so I guess we're stuck with that. However, it suggests an alternative way round the problem to that which I suggested, above. You can use the following to create the axis before asking panel to manage it - the effect is that the axis gets created with the appropriate scale, and then gets handed to panel for position and font management. either approach ends up with the same result, so whichever you find more intuitive.

cheers, ben


>> figure; p = panel;
>> semilogy(x,y,'r','linewidth',2.5);

12 Jul 2012 Ben Mitch

Hi Jesper

I don't know if it's related to the EPS thing...

google "matlab export dashed eps"

In any case, I doubt it's related to panel. panel uses "print" to export, so try using the print function directly and see how that goes. get back to me if it does seem to be panel-related.


ps. you might try a different renderer on the figure, see if that helps. each of the renderers has something it doesn't do well, though.

12 Jul 2012 Jesper

Hi, I have a problem, when exporting figures with dashed or dotted lines. They almost appear as solid lines when I use -rh and -rp resolution. Is there a solution? Rendering?

12 Jul 2012 Ben Mitch

this comments page is really annoying, the way it swallows questions! i've just noticed that my answer to Eric was swallowed too. d'oh.

Eric - the brief answer is that when you set p(1).de.margintop to 50, you're setting all p(1) (the left column) 's descendants to a 50mm top margin, for a total 250mm of margin to be found in the vertical dimension. this is unlikely to fit on your screen, hence the warning and the hidden panels. perhaps you are looking to set just the topmargin of p(1), i.e. p(1).margintop = 50?


12 Jul 2012 Ben Mitch

Hi Brendan - your question seems to have disappeared. I'll briefly answer it anyway - since ax1 is managed and ax2 is not, they will get out of sync whenever the window is resized (in your example, they may never be sized, because you use 'defer' but do not make a call to refresh() at the end). it would be nice, i suppose, if panel managed both ax1 and ax2. i'll look into this when i get back from travelling, it should be easy, and will post a new version probably (in about a week). in the meantime, you can always use set(ax2, 'position', get(ax1, 'position')) to re-sync the two axes, but that's not a viable solution for exporting. thanks for picking that up, i think that will be a useful fix.


11 Jul 2012 Brendan Sullivan  
10 Jul 2012 Ben Mitch

(note that that last example, p(1).rightmargin, is specific to the layout used in demopanel6, i.e. two columns, rather than being a general rule!)

10 Jul 2012 Eric Bryant

Ben, thanks very much for this contribution. There are a couple of things I don't understand about margins, however. For example:

>> demopanel6
>> p(1).de.margintop=50;
Warning: a panel had zero size, and the managed object was hidden ...
>> p(1).de.margintop=0;
>> p(2).de.margintop=50;
[No warning]

Looked at your documentation. Again, much appreciated,

05 Jun 2012 Ben Mitch

Hi Dan, thanks for the comments. I'm not sure quite why a panel axis does not respond to semilogy as it should, I'll look into it if it ever needs a broader update. In any case, semilogy() just sets the value "yscale", so you can use:

plot(x, y, etc.)
set(gca, 'yscale', 'log')

I think that amounts to the same thing.


01 Jun 2012 Dan

Ben, great code and thanks for providing. I've been using it a lot lately. I'm trying to use the semilogy function in one of my panels, but the figure then just shows a normal y-axis. Here is sample code:


Is there a way to use semilogy with panel.m?


01 May 2012 Derek Nokes

Thanks Ben!

01 May 2012 Ben Mitch

hi Derek

see demopanel4, or try the following:

p = panel();
p.pack([70 30], [80 20]);
p(1, 1).select(); plot(y1);
p(1, 2).select(); plot(y2);

that should put you in the same space,


01 May 2012 Derek Nokes

In a previous version of panel I used to do something like this:

p = panel(gcf, [2 2], [70 30],[80 20]);
select(p{1}); plot(y1)
select(p{2}); plot(y2)
select(p{3}); hist(y1,100)
select(p{4}); hist(y2,100)

How do I do something simple like this in the newest version of panel?

30 Apr 2012 Derek Nokes  
16 Mar 2012 Ben Mitch

hi Per

i) if you have the opt toolbox installed, now:

on my machine linprog takes about 80ms for demopanel1. if your linprog is taking 1 sec, and it's the mathworks version, i guess that's just a cost to using LP to do the layout. i might try and optimise the definition of the problem at some point, but i'm not sure if it's possible, i think i tried that last year.

ii) if you don't:

the included linprog solver isn't optimised, and runs slow. if you can track down a faster, freely available, solver, i'd gladly trial it for inclusion in a future release.

on my machine, demopanel1 takes 1.25s. of this, 0.45s is the plotting code. once this is snipped out, most of the rest is sluggish property referencing and function nesting, which is frankly embarassing, but i'm afraid i just don't have time right now to work on optimising this (maybe in april :)). to be fair, demopanel1 is a complex layout; in my everyday use (one to six panels in a grid, say), i don't notice any overhead. but as ever - your mileage may vary.


16 Mar 2012 Per Nordlöw

The performance is still close to unacceptable to me. Running demopanel1.m takes 1.8 seconds out of which 1 second for the linprog code. Why so long? I'm sitting on a pretty descent laptop, Dual-Core 4 Gb memory, DELL PRECISION M6400 with MATLAB 2011b.

15 Mar 2012 Ben Mitch

A note: On 2008b, and possibly later versions I haven't tested, the fact that the resizeCallback() and closeCallback() are private makes things not work. You can fix this by removing the "Access = Private" modifier on that section of "methods". It works fine in later versions, they must have changed the access rules I guess.

24 Feb 2012 Imran  
31 Jan 2012 Ben Mitch

[edited email exchange with "Steffen"]

>> I was wondering: Is it possible to set the background color of the exported figure? I tried
>> set(gcf,'Color',[0,0,0])
>> In the matlab window the background is black. But after p.export the background is white again.
>> What am I doing wrong :?

> set(gcf, 'Color', [0 0 0], 'InvertHardcopy', 'off')
> cheers
> ben

25 Jan 2012 Ben Mitch

Hi Jesper

Forgive me, I was just using Panel myself today and noticed strange behaviour with respect to smoothing and import into Word. Suddenly clicked that I was seeing what you were flagging up the other day. Sorry, I did do some testing before and thought I'd got to the bottom of what you were seeing. Clearly, not - but I understand now :).

This is fixed now for PNG and TIF filetypes which now import correctly whether smoothed or not. Looks like JPEG does not include a DPI setting at all, or at least not one that I can make work. JPEG's not very useful, here, anyway. Next release of Panel will include the fix.

Thanks for the heads up :)

19 Jan 2012 Mukhtar Ullah

Thanks Ben. That is the kind of an answer I was expecting. I had this wrong perception that I can only access methods from an instance p, but you saved me!

Best regards

18 Jan 2012 Ben Mitch

Hi Mukhtar, did you try...

p = panel.recover(gcf);



18 Jan 2012 Mukhtar Ullah

Sorry, I forgot one line. Following is the correct code I use

cvars = who;
foundpanel = false;
for i=1:numel(cvars)
foundpanel = evalin('base', ['isa(' cvars{i} ',''panel'')']);
catch erri
if foundpanel

04 Jan 2012 Ben Mitch

Hi Jesper

Yeah, that's right. By scaling it you're overriding the default DPI either set in the file or assumed by Word.

Some image formats can include a resolution setting (TIFF, PNG, also JPEG?). However, these settings don't propagate to the image file through Matlab's print() function (at least, not to my testing). Panel does not attempt to fix up this information after print() is called because, well, because you're the first person who's flagged it up :). I use Latex for documents, which ignores image DPI, so I'd not noticed.

Erm... It would require either binary hacking or a time-consuming imread()/imwrite() cycle, I guess, to fix it. And Matlab's imwrite() appears not to provide access to these fields for JPEGs. Potentially this could be done, would it make a big difference to you? In any case, I won't prioritise it since the scaling is easy enough.

If you're using PNG (looks like it), you could add it yourself as a read/write step after p.export(), something like:

function set_png_dpi(filename, dpi)

im = imread(filename);
dpm = dpi / 25.4 * 1000;
imwrite(im, filename, ...
'XResolution', dpm, ...
'YResolution', dpm, ...
'ResolutionUnit', 'meter');

Inefficient as hell, but would do what you want. If anyone has a smarter solution, I'll gladly consider adding it to Panel.


04 Jan 2012 Jesper

Thanks Ben, I get 4016x2482 in both cases. But the un-smoothed figure fits directly into a A4 Word document, while the smoothed one needs to be down-scaled to fit...

04 Jan 2012 Ben Mitch

Hi Jesper - thanks for your feedback.

That command produces an image size of 4019 by 2486 pixels on my machine. Without the smoothing, i.e. '-rp', it is 4019 by 2487 (i.e. only one pixel different). What sizes do you get?

Note that this is "170x105mm" only in the sense that, if you print/display that bitmap file at 600 DPI (as chosen by "p"), it will be 170x105mm in size, and the fonts, lines and symbols in the image will be at the point sizes you used when you created them. That meta-information (600 DPI) is _not_ encoded in the image file, as it can be, I believe, in a jpeg file. Thus, if you open it in something like photoshop, you may be surprised at the size it is displayed at, but that is only a matter of zoom level.

Hope that helps

04 Jan 2012 Jesper

Hey, this seems to be quite good! But I have a problem with exporting.
I was expecting a 170x105mm figure with:
p.export('myfig' '-rp/2')
But it turns out to be much bigger. Without the smoothing it is as expected. Am I missing something?

14 Dec 2011 Mukhtar Ullah

Thanks Ben Mitch for the update. I hope others find that useful too.

13 Dec 2011 Ben Mitch

Have just uploaded a new version (2.2) with the flag you need, Mukhtar. Cheers.

11 Dec 2011 Mukhtar Ullah  
11 Dec 2011 Mukhtar Ullah

Dear Ben, thank you for a prompt reply. Commenting out those lines does solve the problem as you guessed. Yes, it would be useful if you add that flag. The reason I need to use different fonts for different text objects is because text objects having math formulas are better in a roman font instead of the default Arial which only suits pure text only.

11 Dec 2011 Ben Mitch

Hi Mukhtar. Thanks for your comments.

Yes, Panel handles fonts (face, size) globally for each panel layout. So, whenever you do anything that causes the panel layout to be re-rendered (e.g. change a margin on a panel for which redrawing is not deferred, as in your case), all fonts of all managed objects will be set back to the default for the layout. It didn't cross my mind that somebody might want to use different fonts for different objects, I'm afraid. Now... what to do about it.

One way would be to provide another flag to the constructor, to turn off font management for that layout, so that the user can do it themselves (fonts would revert to being managed by Matlab, and you could do what you are trying to do). You could trial this by commenting out lines 3010 to 3015 (assuming you are using version 2.1). Does this then do what you want? If so, I'll add this flag and publish a new version.


11 Dec 2011 Mukhtar Ullah

Dear Ben Mitch, this problem is arising again and I think I found the reason why. It depends on whether you set panel margins before or after plotting. So wheraas the following works
p = panel();p.pack(2, 2); = 2;
p(1).marginbottom = 10;
p.margin = [10 8 2 8];
% your plotting commands some of which % change the fontname property

But the following will give you the problem:

p = panel();p.pack(2, 2);
% your plotting commands some of which % change the fontname property = 2;
p(1).marginbottom = 10;
p.margin = [10 8 2 8];

It is driving my nerves crazy. Would be nice if you could fix this. Thanks.

09 Dec 2011 Mukhtar Ullah

I have to take my comment back. The culprit was another piece of code.

09 Dec 2011 Mukhtar Ullah

This function is very useful. One thing, however, could be fixed by the author: it does not respect font specification on an individual basis. Though it is possible to specify a global FontName property, it does not respect the specification for a particular text object. For example, the following will not give the expected result:
xlabel('X(t)', 'FontName', 'Times-Roman');

21 Nov 2011 Ben Mitch

Hi Per. Yes, it's slow without the opt toolbox installed, unfortunately. At some point I may find time to incorporate a fast solver for the layout; until then this will be a problem for complex layouts without that toolbox. If you are using panel for producing final figures, you can use the "defer" argument (see "doc panel/panel"), and the layout will only be computed when you call export. Not ideal, I know.

For the padding (margins), have you looked through the examples in the docs? Particularly, see "demopanel5". Or, try " = 0" as a starting point, then increase margins on individual panels or parent panels until you get the layout you need.

Hope that helps.

10 Nov 2011 Per Nordlöw

Idea is good. However, for some reason the performance becomes unusable bad for grids containing around 20 axeses. I have to around 10 seconds for a redraw. I do not have Opt Toolbox installed. I'm using Linux and HW OpenGL on an Nvidia-equipped Dell Precision M6400. I also find it hard to pad axeses grids in an optimal way so that titles and labels are displayed without covering each other. If these things are fixed I will rate this as a five-star product.

06 Oct 2011 georg

one of my posts got lost, that's why the last message doesn't make sense ... anyway, everything is working now

05 Oct 2011 georg

sorry, I was wrong. I was just wondering how you did the recover after the figure was closed, so I stumbled upon the persistent variables and the mlock call. But the mlock isn't in the dispatcher anyway, so that has got nothing to do with it ...

05 Oct 2011 Ben Mitch

hi georg, i've looked into this. the long and short is, if you call "clf" whilst a panel is managing the figure, you pull out the rug from under panel, and there's no way i can see to detect this. i've updated the code so that the resulting "invalid handle" errors are hidden, rendering this condition harmless, but still it seems that calling "clf" in this way is not the "right" thing to do. do any of these alternatives suit you?

1) if you want to build a fresh set of panels from scratch, just do so (call "p=panel" to create the root). any existing panels will be deleted automatically (though see "demopanelE").

2) if you want to clear the figure and plot into it again without using panel, use "delete(p)", where "p" is your root panel. the figure is now clear of any panels and panel axes. if you left some other stuff in there, you can call "clf" afterwards to clean this up.

let me know if these alternatives make sense. i can see that the expected behaviour on clf would be to delete all associated panels, as well as all graphics handle objects. i wonder if there is any way to do it, though. if anyone knows a way to detect a call to clf, please do pass it on.


05 Oct 2011 Ben Mitch

hi georg. yeah you're right, there's something up there. it is supposed to disengage itself following a clf call; i must have been messing around and left things untidy. i'll look into it when i get a chance. cheers.

05 Oct 2011 georg

Great! love it, especially the print functionality. Though, I think there is a problem with the delete function. I keep getting errors in case I use clf and reset the Figure position afterwards. (I am trying to reuse the same figure multiple times but have different numbers of subplots in it.) Suggestion: either provide a panel.clf() function or unregister the callback functions from the parent handle (and anything else that my belong to the panel)

05 Oct 2011 Ben Mitch

hi Warwick - i think this must be a problem with your local "linprog", since the one provided with panel is not named the same. try "which linprog" or "edit linprog" to see what it resolves to, and delete it or move it as necessary. panel should then start working.

05 Oct 2011 georg  
02 Oct 2011 Warwick

Trying to run demopanel1, etc.

keep getting error.
"Error: File: linprog.m Line: 27 Column: 4
A BREAK statement appeared outside of a loop. Use RETURN instead."

14 Aug 2011 Ben Mitch

Ian - Sorry, I haven't had time to look at this. In the meantime, you can make this call to disable the layout process following a resize:

set(p.figure, 'ResizeFcn', [])

Technically a hack, but I can't think why it would cause any side effects. Cheers.

14 Aug 2011 Ben Mitch

Hi Stewart - extract it anywhere, and just add the file "panel.m" to your Matlab path (using "addpath", or "pathtool"). Cheers

14 Aug 2011 Stewart Wiseman

Newbie question! I downloaded Panel, where do I extract it to? Thanks..

14 Jul 2011 Ian

I remove all space and ticks and thus 15x15 actually works well on a decent monitor! 15x15 is probably an upper limit though (more because it takes ages to record data from large matrices) :-P

Yes, I do resize a lot - I use Matlab as an online display for data coming in from neuronal recordings, and resize given other programs and the size of the current data grid. Again, if it remains slow, I'll just know *not* to resize, but being able to turn the physical sizing on/off would be great!

13 Jul 2011 Ben Mitch

15x15! wow, you're just to crazy to be real, such large numbers computers just can't handle! seriously, does that really fit on screen?

errr... yeah well there might be a bit more to squeeze out of it. but the resize thing - since panel performs layout to a physical size, it needs to remake the layout when the physical size of the window changes. subplot uses relative units, so there is no re-layout necessary on resize. it would be easy enough, for panel, to provide a flag that turned off physical sizing on resize, or that turned off physical sizing for the figure window (letting it operate only on export). would that be useful for you? do you resize windows a lot, then? :)

i may have to make an interim release with these mods - it's taking a while to get this linprog license sorted out.

13 Jul 2011 Ian

I was getting about 4.8 seconds with original panel and about 1.5-2 secs with subplot. Note subplot seems to do a lot of property enumeration too...

I'd normally not be worried, but I'm using panel to display data as it comes in in real time and long plotting times cause matlab to freeze enough that I lose my data sync (I saw this with 15x15 matrix)...

Has resizing the figure performance also improved now?

12 Jul 2011 Ben Mitch

Got it down to only 25-30% slower now. I'm getting about 2.45 secs for a 9x9 layout using subplot, and 3.15 secs for the 9x9 using panel. Are these numbers comparable to what you're seeing, Ian?

12 Jul 2011 Ben Mitch

Ian - dunno what happened there, think I overwrote my own first comment. In any case, the comment above tells the end result, even if it reads a bit funny :). Cheers.

12 Jul 2011 Ben Mitch

Ach, I had a quick look since you brought it up. I used demopanel2(N=9) as a test case, as you suggested. Bit of code tidying has got the speed down from 3x longer than subplot to 1.6x longer. That line you highlighted _is_ an overhead, but preallocation doesn't seem to help.

In any case, at only 60% longer than subplot, I'm not too concerned, but I'll probably have another look, as I said, later in the year. The profiler suggests we could get another 10-15% speedup by more efficient property resolution, which would put us pretty closely in line with subplot. Might be able to avoid most of the calls to control fonts, as well, when the user hasn't specified different fonts. With all that, would probably be getting times not dissimilar to those from subplot.


11 Jul 2011 Ian

Hi Ben, when I increase the number of axes to manage, panel starts to get very slow. To reproduce, change demopanel2 to use 9 x 9 axes, panel starts to take substantially longer than subplot. Profiling, the largest time taken is calling this line (839 times):

p.state.lin(dim).A = [p.state.lin(dim).A; a];

Wonder if preallocating wouldn't help? Resizing the figure I think also triggers this (called 2264 times).

02 Jul 2011 Prakash Manandhar  
23 Jun 2011 Nate Jensen

I like it. I'd like to throw some constructive criticism in here, but I haven't played around with it enough to do that yet. So far so good. Keep it up.

20 Jun 2011 Ben Mitch

thanks - my matlab does not document the -dpdf option, or else i couldn't find it.

ok, have done that, seems to work fine. this will appear in the next release (just waiting for permission to include linprog...).

20 Jun 2011 Joshua

my usual print command is this:

wh=[2 3]; % width and height of page to print on
set(gcf,'PaperSize',wh,'PaperPosition',[0 0 wh],'Color','w');

i often have problems with font sizes, in that the axis-labels get partially cut off. i'm hoping that panel will somewhat alleviate this issue (in addition to all the other nice features that it has).

anyway, is that what you were looking for?

19 Jun 2011 Ben Mitch

Hi Joshua - I'd be happy to include pdf support. Perhaps you can point me at how to export a figure to pdf using the command line? I looked at the docs for the "print" function and I can't see any mention.

19 Jun 2011 Joshua

this looks great! before i could adopt it, however, i would need to export to pdf. i modified the code a bit to do it, but it wasn't perfect (paper size needed to be updated too). anyway, i might do it for me. if the code was hosted somewhere like github, it'd be super easy for you to see my changes. but i imagine you could do it better, and quicker. any thoughts?

-- jovo

ps - the reason i want pdf over ps/eps is that on a mac, pdf viewer is nice and built-in, so i always store vector graphics as a pdf.

24 May 2011 Daniel

gotta thank you for your extensive work :)

24 May 2011 Ben Mitch

Thanks Daniel - this does indeed do the job. I'm just liaising with the author about licensing, will hopefully release a repack that doesn't need the opt toolbox soon. Thanks for the heads up :).

24 May 2011 Daniel

There is a function called linprog in the FEX (see But the inputs are different to the optimtool linprog. Maybe you'll find a solution with that..

23 May 2011 Ben Mitch

Hi Daniel. Uh-oh - that never even crossed my mind. Err... does everyone in the world have the optimization toolbox...?

Well, the LP problem is pretty straightforward. Wonder how difficult it is to program an LP solver, probably not too tough. Or perhaps there's some source code knocking around on the interweb... Any pointers appreciated...

In the meantime, Daniel is right, you'll need the optimization toolbox. Sorry.

23 May 2011 Daniel

seems to require optimization toolbox (linprog()). have we got workarounds for that?

23 May 2011 Ian

The V2.0 update for panel is wonderful, very well documented code (including lots of demonstrations), refactored into a single classdef, and as it now works within uipanels can now be used as subplot. Panel is wonderfully flexible, and controlling super labels, fonts, and margin management elegantly with very intuitive class methods.

Thanks Ben, this is a really excellent contribution!

09 Mar 2011 Ian

Ben, thanks for adding this to your TODO! I'm also really looking forward to the handle class version of this -- hope it is a single classdef m file for easy install for the lazy :)

Cheers, Ian

07 Mar 2011 Ben Mitch

Hi Ian

I'm just preparing a new version of Panel now (handle class based). I'll put this on the TODO list before the release. Sounds straighforward, doesn't it? I wonder if there's anything else that someone might want to use as a parent of panel...

Incidentally, you can probably do what you want with the existing version. Set panel on the whole figure, then pack it with a child with absolute positioning, with position equal to that of the uipanel. Not quite as slick, but i think it would work. e.g...

u = uipanel;
set(u, 'position', pp)
p = panel;
q = p.pack(pp);
r = q.pack( ... etc.)


07 Mar 2011 Ian

What would be great is if we could attach this not only to a figure, but a panel within a figure. I have an existing UI using subplot setting the Parent as a uipanel. This allows me to have a set of UI buttons etc in one panel and my plots in another. I'd love to use panel, but trying to force it to use a uipanel as a parent fails...

02 Mar 2011 Ben Mitch

Hi Niko - I did as you suggested, was a good idea. Do please try the update, when it comes through, and let me know if you have any problems.

02 Mar 2011 Ben Mitch

Hi Niko - thanks. You mean, I think, so that the xlabel/ylabel were positioned as if the four (say) sub-panels were all one axis. That's a good idea, yeah. I guess another possibility is that you might want to set all the xlabels/ylabels of all the sub-panels through a single command. Both things are possible, but the first sounds particularly useful. I'll look into it.

Thanks for the feedback.

01 Mar 2011 Niko

Very useful tool.

It would be nice to be able to easily add a panel-wide xlabel/ylabel spanning multiple children.

27 Oct 2010 Renay

Thanks for the prompt reply Ben, but I should have read your manual! The following is what I needed:


This turns the screen updating off. Thanks for a great package.

26 Oct 2010 Ben Mitch

Invisible? Not sure what you mean - can you explain further?


26 Oct 2010 Renay

Thanks for the great package.

How would I make the process of exporting a panel 'invisible'.


11 Sep 2010 Ben Mitch

just for info - the latest release incorporates two of suggestions above. you can now use p = panel(gcf, [2 2]) to return a 2x2 (or whatever) grid of panels (further arguments control sizing - see screenshot above). handling of xlabel, xtick and xticklabel is now seamless with the corresponding matlab functions (i think, anyway :). thanks for the feedback :).

28 Aug 2010 ethan reddick  
19 Aug 2010 Ben Mitch

Hi - Thanks for comments.

yes you can change xtick labels. use p.xticklabel = {1 2 ...} where p is a panel. should work just the same as set(gca, 'xticklabel', {1 2 ...}) i think. unfortunately, this didn't find its way into the docs, sorry. next release will have this documented.

yeah, p = panel(2, 2) would be ok i suppose wouldn't it, so long as you just wanted a regular grid layout which i guess we often do. i'll see about adding that. additional pars for sizing... hmmm i'll look into it.

implement using a HANDLE class: yeah, well this was written back in the dark days when such things weren't possible. i do fancy reimplementing at some point, would be slicker. if i ever get the time :)

re the defaults idea, yeah i see what you mean. i'll stick it on the todo list.


17 May 2010 Heeten Choxi

Is there a way to change the values of the xtick labels? I tried doing it with set(axis,'XTickLabel', [new values]) which used to work when I used subplot but doesn't seem to work with panel.


12 May 2010 LP

This appears to have good potential but some suggestions;

* Should have a similar interface to subplot
e.g. p = panel(2,2);
which would return a (2,2) array of panel objects
and perhaps some additional parameters for the relative sizing of each subpannel a-la the input for 'pack'

* Implement using a HANDLE class inheritance

* Allow margins to be set individually so that defaults remain
e.g. axismargin(10,[],[].10);

Good luck!

19 Aug 2010

Added missing documentation; fixed mis-applied tick labels during export bug; added simple constructor syntax for building panel grids all-at-once.

19 Aug 2010

Fixed a minor bug introduced in the last update.

26 Aug 2010

Hopefully, really fixed all the tick label bugs this time. Added management of independently-created axes (like colorbars), idea by Arthur Ward. Added grid-like packing to pack(), as previously added to constructor, panel().

28 Aug 2010

Integrated implementation of native axis properties, so that functions like xlabel() and title() and set(gca, 'xticklabel', ...) now work seamlessly with panel. Big tidy of the documentation too.

28 Aug 2010

20% faster rendering, fixed figure units bug from years ago, implemented correct handling of "orphaned" panel references.

02 Mar 2011

Added recursive and group labelling and titling, as suggested by Niko.

22 May 2011

Release of Version 2.0. This release moves to a single implementation file, and moves to a much simpler system for control of layout.

25 May 2011

Updated information: R2008a is required, based on

20 Jul 2011

Version 2.1 (20 Jul 2011) includes a built-in linear programming solver (due to Jeff Stuart, available on FEX). This allows users without the Optimisation Toolbox to use Panel. Some performance improvements, and added an option to export to PDF.

13 Dec 2011

Version 2.2. Some improvements to the documentation, added the flag "no-manage-font" to disable Panel's font management. Otherwise, unchanged, straight swap.

26 Jan 2012

Release 2.3, fixed a few bugs is all.

13 Mar 2012

Release 2.4. Fixes one bug, whereby a single panel in a figure does not get positioned until the figure is resized.

23 Jul 2012

Added support for multiple objects per panel (e.g. 2 axes, as suggested by Brendan, see demopanelG). Couple of bugs fixed.

NB: Significant change, consider this BETA, please: revert to 2.4 if problems. Can't find anything wrong with it, though.

24 Jul 2012

Release 2.6. Adds support for SVG export (through plot2svg), plus improved documentation.

21 Mar 2013

Version 2.7. Changes: added demo of insets (tx Ann Hickox); added panel.plot() to work around poor rendering of dashed lines.

14 Apr 2013

Release 2.8. Withdraws panel.plot() in favour of panel.fixdash(), which has the same aim but is much less crude.

03 May 2013

Release 2.9. Export infers image format from file extension; units can be set in constructor; adds group descriptor "family"; adds panel.version(); adds LNCS page size.

13 May 2013

Release 2.10: Removes optimisation (LP) problem from layout in favour of analytical solution (faster, does not need opt toolbox). Supports panels of fixed physical size. Supports various packing modes not previously supported.

15 May 2013

Added link to FAQ.

Contact us