subsubplot.m : Nested subplots in Matlab
This script can be used to partition a figure into a complex set of axes by recursivly creating subplots within subplots.
There are quite a few options for fine control, but it basically starts with a full figure, and breaks that into an N by M grid of axes, then can do the same for any/each of these N*M children, and so on... The function takes a data structure describing how you want the figure partitioned, and returns a list of handles to the axes created.
Basic Example
This example shows subsubplot without the more complex options. The structure stored in the variable 'top' (at can be named anything) stores all information describing what you want. It starts by splitting the entire figure into a 4x1 grid (top.sp = [4 1]), then subsequently splits some of this children, .c(i), further (1<=i<=N, numbered how matlab usually numbers subplots). The main function, subsubplot.m, takes a structure (here named 'top'), creates the axes, and returns a list of handles to those axes. The function subsubplot_showlayout.m will show how the layout will look and display numbers on each axes according to the order in the vector returned from subsubplot.
% explicitly set each subplot, with no other options clear top; top.sp = [4 1]; top.c(1).sp = [1 2]; top.c(2).sp = [1 2]; top.c(2).c(1).sp = [2 2]; top.c(2).c(1).c(1).sp = [3 3]; top.c(2).c(1).c(3).sp = [3 3]; top.c(2).c(1).c(4).sp = [3 3]; top.c(2).c(1).c(5).sp = [1 2]; top.c(2).c(1).c(21).sp = [2 2]; top.c(4).sp = [1 4]; top.c(4).c(2).sp = [2 1]; top.c(4).c(3).sp = [3 1]; top.c(4).c(4).sp = [4 1]; subsubplot_showlayout(top);

You can do simple one-liners with matlab's struct() function:
'H = subsubplot(struct('sp',[4 1],'pad',.04));');
More options
There are several other options than can be applied to each node in the structure (ie the top level or any child, .c(i), below it). The "[R_]" in front of properties means that when when "R_" is added to front of option name, then that property will be inhereted to all decendents which do not specify that property (or a new "R_*" is encountered). Note that these options are not independent - a given figure layout may be accomplished in different ways.
- (node).sp = [R C]
.sp ("subplot") is the only required field if you want this node to partitioned. It must be 2-dimensional, specifying the number of rows and columns to be created within the current node.
- (node).[R_]skip = [array]
Default = [ ]
Calling .sp = [R C] on a node will create R*C axes. You can use .skip to specify that some of these should not be created. It should contain a selection of indices 1:(R*C). So, for example, .skip = 1:2:(R*C) will look like a checkerboard, only creating every other axes in a RxC grid.
- (node).[R_]pad
Default = zeros(R*C,4)
Specifies how to pad the axes in a given subplot, creating a border of blank space around each one. Can be specified in 4 different forms:
- size 1x1: (node).[R_]pad = [globalpad]
- size 1x2: (node).[R_]pad = [inner outer]
- size 1x4: (node).[R_]pad = [top right bottom left]
- size Nx4: (node).[R_]pad = [t1 r1 b1 l1; t2 r2 b2 l2; ... tN rN bN lN]
1x1 (globalpad) puts the specified padding around all four sides of all subplots. inner/outer refers to which of the subplots' sides touch the border of the parent rectangle vs. only touch other subplots. This sounds confusing, but is often the one to use for best looking results - see examples. The 1x4 case lets you chose a different value for all fours sides, but this is applied to all subplots. Finally, Nx4 lets you specify a different border for all sides of all subplots of the given node.
All values should be specified in terms of fractions [0,1] of the size of the entire figure. Be careful, you can get an error by putting padding in that won't fit inside the axes itself.
- (node).init = [left bottom width height]
Default = [0 0 1 1]
Specifying (node).sp will fill the entire space allocated to the parent, (node) (after taking into account .pad). Using .init will start the given subplot in the specified rectangle. Each value should be in range [0,1].
More Examples
% Figure 2 - clear top; top.sp = [2 2]; top.c(1).sp = [2 2]; top.c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).c(1).c(1).sp = [2 2];
% Figure 3 - top.sp = [4 4]; for i=1:16 k = round(rand(1,2)*3)+1; top.c(i).sp = k; top.c(i).pad = .03.*rand(prod(k),4); end
top.sp = [3 3]; top.skip = 2:2:8;
top.sp = [2 2]; top.skip = [2 3]; top.c(1).sp = [2 2]; top.c(1).skip = [2 3]; top.c(1).c(1).sp = [2 2]; top.c(1).c(1).skip = [2 3]; top.c(1).c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).skip = [2 3]; top.c(1).c(1).c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).c(1).skip = [2 3]; top.c(1).c(1).c(1).c(1).c(1).sp = [2 2]; top.c(1).c(1).c(1).c(1).c(1).skip = [2 3];
%----- Sierpinski carpet, depth 3 --------
top.sp = [3 3];
top.skip = 5;
for i=1:9
if (i~=5)
top.c(i).sp = [3 3];
top.c(i).skip = 5;
for k=1:9
if (i~=5)
top.c(i).c(k).sp = [3 3];
top.c(i).c(k).skip = 5;
end
end
end
end
Files
- subsubplot.m: creates nested subplots
- subsubplot_showlayout.m: draws a simple image in each axes to display a given layout and numbers the axes according to their order returned by subsubplot.m
- subsubplot_examples.m: a bunch of examples of how you can use subsubplot.m (those shown above)




