File Exchange Pick of the Week

Figure margins, subplot spacings, and more… 5

Posted by Jiro Doke,

Jiro's pick this week is tightfig by Richard Crozier.

Contents

Subplot and its large margins

In response to my last post, Richard Johnson asked whether we could write posts that compared similar entries, for instance "arrows" and "waitbars". Just for kicks, I searched the File Exchange for entries with the tag "waitbar", and it returned close to 70. One of these days, I may get around to testing all of them, but not right now. Hey, even the fact that there are a lot of "waitbar" entries has already been blogged about.

With that daunting task of reviewing 70 files weighing heavily in my head, I came across Richard Crozier's tightfig. It caught my eye, because I like anything related to visualization, and people have asked about (how to get rid of) large margins in subplots. Then, I remembered seeing something similar before. In fact, Brett picked "tight subplot" earlier this year. Nice! Maybe I could compare these two files.

After reading through the comments for tightfig, one of the commenters mentioned 5 other similar entries (subplot_tight, spaceplots, subplot1, subplotplus, tight_subplot). Sounds good! That's a more reasonable number of entries to review. Luckily, Richard has already done some reviews himself, but I'll try to add some of mine below.

tightfig

The first thing I want to mention is that tightfig has a different purpose than the other entries. The description on the entry page explains the purpose very well: "Alters a figure so that it has the minimum size necessary to enclose all axes in the figure without excess space around them." Note that this is about making the outer bounds of the figure tight. Its intention is not to modify any of the spacings between the axes, which is the primary purpose of the other entries. I'll say more on this later.

figure('Color', [.8 .8 .8]);

subplot(2,2,1);
surf(peaks); shading interp
title('Peaks');
ylabel(colorbar, 'Color Scale');

subplot(2,2,2);
plot(rand(10,3));
xlabel('time');
ylabel('money');

subplot(2,2,3);
imshow('peppers.png');

subplot(2,2,4);
surf(membrane(1));
xlabel('x label');
ylabel('y label');
zlabel('z label');

tightfig is extremely simple to use. You just call it after creating your plots, and it applies to the current figure. That's one of my favorite things about this entry.

tightfig;

Review of the other entries

Before looking into the other entries, I'd like to point out that the use case for tightfig is quite different from that of the others. One is for tightening the figure boundary, and the others are for controlling/tightening the axes boundaries. So it may not be an apples-to-apples comparison. Nonetheless, here I go. Oh, and try not to get confused with all the names. :)

subplot_tight

I find subplot_tight to be the easiest to use, since it has a syntax that is closest to the MATLAB function subplot. Not surprisingly, it is a wrapper around subplot, with an added option to specify the spacing between an axes and its neighbors. Because it's a wrapper, you can make use of the vector input syntax for the 3rd parameter (see below). The author also supplies a demo script to recreate his screenshot.

figure;
subplot_tight(2, 2, 1, .1);
subplot_tight(2, 2, 2, .05);
subplot_tight(2, 2, [3 4], .05);

tight_subplot and subplot1

tight_subplot and subplot1 are quite similar. They both allow you to lay out a grid of subplots with arbitrary spacings and margins. tight_subplot is compact with just those parameters, i.e. spacing and margin, while subplot1 lets you control other axes properties, such as tick labels, label font size, and axes scale. I like that it gives me the ability to have the tick labels only displayed on the outside with subplot1 (see example below).

% tight_subplot

figure;
hA = tight_subplot(3, 2, [.01 .03], [.1 .01], [.01 .01]);

% subplot1

figure;
subplot1(3, 2, 'Gap', [.01 .03], 'XTickL', 'Margin', 'YTickL', 'Margin');

spaceplots

spaceplots works like tightfig, in that you create your figure first with subplots, then call spaceplots to adjust the spacings and margins. This function, unlike tightfig, will allow you to adjust the spacings between axes, not just the outside margin. The part that I like most is that it will work with irregular-grid subplots (see example below). However, there's a caveat that it only works on axes created using subplot.

figure;
subplot(2, 2, [1 2]); plot(rand(10, 3));
subplot(2, 2, 3); surf(peaks); title('Peaks')
subplot(2, 2, 4); contourf(peaks);

% 0 margin, 0.02 (normalized) spacing
spaceplots([0 0 0 0], [.02 .02]);

subplotplus

subplotplus is the king of custom subplots. It comes with a price of somewhat cryptic syntax, but once you understand it (with the help of an example script), it can let you custom layout your subplots in any configuration you like. It even includes the ability to "glue" axes together so that they have a common axis.

cell71={{['-g']};{['-g']};{['-g']};{['-g']};{['-g']};{['-g']};{['-g']}};
cell41={{['-g']};{['-g']};{['-g']};{['-g']}};

figure;
C = {{{{[]},{[]}};cell41},cell71};
[h,labelfontsize] = subplotplus(C);

Conclusion

So what have I concluded from this review? There are multiple solutions to a problem! They all have unique ways of tackling the problem, and some solve a slightly different problem than others. Overall, I prefer the "post-processing" type functions, tightfig and spaceplots. I tend to do my exploratory plotting in a rough state, and once I have a plot I like, then I start making things look nicer. But of course, with an interactive tool like MATLAB, even the "pre-processing" type functions can be introduced at a later step.

Comments

I'm interested to hear from anyone who has looked at all/any/one of these entries. Give us your feedback here.


Get the MATLAB code

Published with MATLAB® R2012b

5 CommentsOldest to Newest

I’ve got these functions, I find myself using a combination of subplots+spaceplots and tight_subplot.

Spaceplots respects titles but doesn’t let you space margins, also sometimes makes images of uneven size. For example in a 3×3 subplot one may have 8 images of 200×200 pixels and 1 scatterplot. Spaceplots made the images on the row&column of the scatterplot smaller than the other images, so they’d rather be the same size as the plot()…

tight_subplot (no real preference over the similar ones, I just prefer working with object handles) fits a maximal amount of images into my 16:9 screen :)
I find myself making titles as normal and then moving them down abit into the image–since parts outside my ROI are black anyway I use white text and it looks fine. This means changing the properties of the title handles of the axes. Like after plotting:

::mytitles = get(get(gcf,’Children’),’Title’)
set([mytitles{:}],’Position’,[190 0],’Color’,’w’,’VerticalAlignment’,’top’)

For simple figures you do not really need the FEX contributions. The spacing around the edges of the subplots is controlled with a field of the application data. You can remove all the spacing with

setappdata(gcf, ‘SubplotDefaultAxesLocation’, [0,0,1,1])

Controlling the spacing between subplots is harder since TMW have hardcoded it into subplot.m. In R2011a the spacing is controlled by line 130 of subplot.m

inset = [.02, .018, .004, .01]; % [left bottom right top]

you can copy the function and set it to be anything you want (or better yet, make it depend on the application data).

I have a long standing enhancement request asking for these to be made properties of the figure such that they can be modified with set/get.

These postings are the author's and don't necessarily represent the opinions of MathWorks.