Nested tiledlayout: can parent tiles have different widths depending on number of child tiles?

Hello,
I am trying to plot several vertical profiles grouped into categories in one figure. Each category contains a different number of profiles. My goal is for the width of each category block to scale with the number of profiles it contains, so that each individual profile has the same width across the whole figure.
My code:
% outer layout
out = tiledlayout(1, length(groups), 'TileSpacing', 'compact', 'Padding', 'compact');
Unrecognized function or variable 'groups'.
for i = 1:length(groups)
idx = groups{i};
n = length(idx);
% inner layout for this group
inn = tiledlayout(out, 1, n, 'TileSpacing', 'compact', 'Padding', 'compact');
inn.Layout.Tile = i;
title(inn, group_titles{i}, 'FontSize', 12, 'FontWeight', 'bold');
for j = 1:n
k = idx(j);
ax = nexttile(inn);
h = imagesc([0 1], depth_vec, salinity_mat(:, k));
clim([cmin cmax])
h.AlphaData = ~isnan(salinity_mat(:, k));
title(ax, order{k})
if k == 1
ylabel('Depth (m)')
else
set(ax, 'YTickLabel', [])
end
set(ax, 'XTick', [])
end
end

Answers (2)

It might be better to us e a grouped bar plot, e.g.,
Y = [5 3 7 0 0;
6 4 2 1 0;
4 8 5 1 6];
gradientGroupedBar(Y)
function gradientGroupedBar(Y)
% Y: [nGroups x nBarsPerGroup]
[nGroups, nBars] = size(Y);
% Basic bar geometry
groupWidth = min(0.8, nBars/(nBars+1.5));
figure; hold on;
for iBar = 1:nBars
% Compute x positions for this bar within each group
x = (1:nGroups) - groupWidth/2 + ...
(2*iBar-1) * groupWidth / (2*nBars);
for iGroup = 1:nGroups
% Bar corners
xL = x(iGroup) - groupWidth/(2*nBars);
xR = x(iGroup) + groupWidth/(2*nBars);
yB = 0;
yT = Y(iGroup,iBar);
N = 1000; % controls smoothness
yVals = linspace(yB, yT, N)';
X = [xL*ones(N,1), xR*ones(N,1)];
Ysurf = [yVals, yVals];
% Smooth gradient values
C = repmat(linspace(0,1,N)', 1, 2);
% Draw surface
surf(X, Ysurf, zeros(N,2), C, ...
'EdgeColor','none', ...
'FaceColor','interp');
end
end
colormap(parula); % choose your gradient
colorbar;
xlim([0.5 nGroups+0.5]);
view(2); % 2D view
box on;
end
I don't think there is an automatic way to do this, but you could specify the TileSpan to achieve (approximately) equal sizes.
rd0 = {{rand(7,3),rand(7,3)},{rand(7,3),rand(7,3),rand(7,3)}}; % fake data
vd0 = cellfun(@numel,rd0); % count images
nd0 = sum(vd0); % total number of images
cs0 = cumsum([1,vd0]); % cummulative count
tl0 = tiledlayout(1,nd0, 'TileSpacing','compact', 'Padding','compact');
for ii = 1:numel(rd0)
rd1 = rd0{ii};
nd1 = numel(rd1);
tl1 = tiledlayout(tl0, 1,nd1, 'TileSpacing','compact', 'Padding','compact');
tl1.Layout.Tile = cs0(ii); % first tile
tl1.Layout.TileSpan = [1,vd0(ii)]; % span
title(tl1, "Title of "+vd0(ii)+" Images", 'FontSize',12, 'FontWeight','bold');
for jj = 1:nd1
ax = nexttile(tl1);
imagesc(ax,rd1{jj});
title(ax, "T"+ii+" Im"+jj)
end
end

Products

Release

R2025b

Asked:

on 20 Mar 2026

Edited:

on 20 Mar 2026

Community Treasure Hunt

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

Start Hunting!