Common legend for each row of tiled layout

21 views (last 30 days)
I am trying to make a compact tiled layout with N rows and 2 columns where the axes of each row share a common legend in MATLAB R2023b. The legend should be positioned above and in between the two axes in each row. I have attempted to do this by adding a legend to one tile in a row, and then repositioning it. However, this changes the size of the axes and causes the legend to overlap the axes
Here's a MWE:
%% Generate the tiled layout and legends
tlh = tiledlayout(2,2,'TileSpacing','Compact');
% Tile 1
nexttile
plot(rand(20,2))
% Tile 2
nexttile
plot(rand(20,2))
lh = legend('sample 1','sample 2');
% Tile 3
nexttile
plot(rand(20,2))
% Tile 4
nexttile
plot(rand(20,2))
lh(2) = legend('sample 3','sample 4');
% Adjust Legend parameters
[lh.Location] = deal('NorthOutside');
[lh.Orientation] = deal('horizontal');
[lh.Units] = deal('normalized');
This looks ok, with nicely-sized plots, but we want the legends to be in the centre.
%% Reposition the legends
for i = 1:length(lh)
lw = lh(i).Position(3);
lh(i).Position(1) = 0.5-lw/2;
end
This makes the legends overlap the axes.
What to do? I can't use the "Layout" options in the legend handle as far as I know; that would only let me place on axis above the figure. I can't change the position of the axes, as these cannot be set manually in a TileChartLayout.
I could do nested tiled layouts, but that seems very cumbersome, especially when I have many more rows.
Thank you

Accepted Answer

Matt J
Matt J on 29 Nov 2023
Edited: Matt J on 29 Nov 2023
I could do nested tiled layouts, but that seems very cumbersome, especially when I have many more rows.
Why?
%% Make Layout Skeleton
[ax,t]=makeLayout(5,4);
%% Populate Axes
for k=1:numel(ax); plot(ax(k), rand(20,2)); end
%% Populate Legends
for i=1:numel(t)
Strings=compose("sample %d.%d",i,1:2);
lh(i) = legend(t(i).Children(1),Strings,'Orientation','horizontal','Units','normalized');
lh(i).Layout.Tile='north';
end
function [ax,t,T]=makeLayout(nrows,ncols)
T = tiledlayout(nrows,1,'TileSpacing','Compact');
k=0;
for i=1:nrows
t(i)=tiledlayout(T,1,ncols,'TileSpacing','Compact');
t(i).Layout.Tile=i;
for j=1:ncols
k=k+1;
ax(k)=nexttile(t(i));
end
end
end

More Answers (1)

Image Analyst
Image Analyst on 29 Nov 2023
Did you try title or sgtitle?
  1 Comment
Delyle Polet
Delyle Polet on 29 Nov 2023
The question asks for a common legend between axes. Is there a way to use title to accomplish this?

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!