Question about aligning x-axes in subplots on the same row in Matlab
11 views (last 30 days)
Show older comments
Dear Matlab experts,
I have a question about creating a plot consisting of 4 subplots arranged in a 2 by 2 grid. I want to align the x-axes of the subplots that are on the same row, while preserving their individual y-limits. I do not want to change the size of any subplot. To provide a visual reference, I have attached a sketch of the plot that I want to produce (Please forgive me for the ugly draw!)
Thank you in advance for your help!
Edit: Thank you for your prompt response, Matlab experts. Your proposed solutions have been effective for this simple case. However, I am having difficulty implementing your suggestions to solve my particular problem. I acknowledge that this is due to my own oversight, as I oversimplified my question. I apologize for any inconvenience this may have caused.
To elaborate further, each subplot in my code contains more than one function and includes vertical error bars as well. To facilitate your understanding, I have included my Matlab code below for your reference. The plot below is created from the given code. As you can see, the x-axises are not yet aligned and the ylim are different across subplots. I would like to have the x-axises aligned (for subplot on the same row) but keep the ylim of individual subplot unchanged. Thank you very much!
rng(12345)
% ----------- generate fake data --------------
% mu = [-1 0 5 -2 1 4 -6 0];
mu = randn(1,8);
MU = [mu,mu*rand(),10*mu*rand(), 100*mu*rand(),...
-mu,mu*rand(),-0.1*mu*rand(), -10*mu*rand()];
vars = [1 0.1 32 4 0.5 10 16 1];
COVMAT = diag([vars,vars*rand(),10*vars*rand(), 100*vars*rand(),...
vars,vars*rand(),10*vars*rand(), 100*vars*rand()]);
sim_data = mvnrnd(MU,COVMAT,100)';
% ----------- config error bars -------------
error_bar_tail_size = 10;
error_bar_size = 2;
% ----------- plotting -------------
fig_count = 9;
fig_num = 1;
for i = 1:8
if fig_count >8
figure(fig_num);
fig_num = fig_num + 1;
fig_count = 1;
end
subplot(2,4,fig_count)
fig_count = fig_count + 1;
idx = ((i-1)*8 + 1):(i*8);
hold on
x = 1:1:4;
percentiles = prctile(sim_data(idx(1:4),:),[2.5 50 97.5],2);
y1 = percentiles(:,2);
yneg1 = abs(y1 - percentiles(:,1));
ypos1 = abs(y1 - percentiles(:,3));
percentiles = prctile(sim_data(idx(5:8),:),[2.5 50 97.5],2);
y2 = percentiles(:,2);
yneg2 = abs(y2 - percentiles(:,1));
ypos2 = abs(y2 - percentiles(:,3));
% plot first error bars
e1 = errorbar(x-0.15,y1,yneg1,ypos1,'.','MarkerSize',27,'CapSize',error_bar_tail_size);
e1.LineWidth = error_bar_size;
% plot second error bars
e2 = errorbar(x+0.15,y2,yneg2,ypos2,'.','MarkerSize',27,'CapSize',error_bar_tail_size);
e2.LineWidth = error_bar_size;
% set axis limits and labels
xlim([0.5 4.5])
yline(0,'LineWidth',1)
xaxisproperties= get(gca, 'XAxis');
xaxisproperties.TickLabelInterpreter = 'latex';
xticks(x)
ax = gca;
ax.FontSize = 18;
title(['subplot ',num2str(i)],'FontSize',22,'Interpreter','latex')
hold off
end
0 Comments
Answers (2)
Dyuman Joshi
on 24 Apr 2023
One way to achieve this is to modify y-limits.
figure
x = linspace(0,10,1e3);
subplot(2,2,1)
y1 = sin(x);
plot(x,y1)
yline(0)
ylim(max(abs(ylim)).*[-1 1])
subplot(2,2,2)
y2 = exp(x);
plot(x,y2)
yline(0)
ylim(max(abs(ylim)).*[-1 1])
subplot(2,2,3)
y3 = -exp(sin(x));
plot(x,y3)
yline(0)
ylim(max(abs(ylim)).*[-1 1])
subplot(2,2,4)
y4 = 10*x.^(1/2);
plot(x,y4)
yline(0)
ylim(max(abs(ylim)).*[-1 1])
Though I feel it would be nice to have an option like
axis center
%or
axis origin
2 Comments
Dyuman Joshi
on 4 May 2023
Apologies for late reply. You can use the above approach here as well
rng(12345)
% ----------- generate fake data --------------
% mu = [-1 0 5 -2 1 4 -6 0];
mu = randn(1,8);
MU = [mu,mu*rand(),10*mu*rand(), 100*mu*rand(),...
-mu,mu*rand(),-0.1*mu*rand(), -10*mu*rand()];
vars = [1 0.1 32 4 0.5 10 16 1];
COVMAT = diag([vars,vars*rand(),10*vars*rand(), 100*vars*rand(),...
vars,vars*rand(),10*vars*rand(), 100*vars*rand()]);
sim_data = mvnrnd(MU,COVMAT,100)';
% ----------- config error bars -------------
error_bar_tail_size = 10;
error_bar_size = 2;
% ----------- plotting -------------
fig_count = 9;
fig_num = 1;
for i = 1:8
if fig_count >8
figure(fig_num);
fig_num = fig_num + 1;
fig_count = 1;
end
subplot(2,4,fig_count)
fig_count = fig_count + 1;
idx = ((i-1)*8 + 1):(i*8);
hold on
x = 1:1:4;
percentiles = prctile(sim_data(idx(1:4),:),[2.5 50 97.5],2);
y1 = percentiles(:,2);
yneg1 = abs(y1 - percentiles(:,1));
ypos1 = abs(y1 - percentiles(:,3));
percentiles = prctile(sim_data(idx(5:8),:),[2.5 50 97.5],2);
y2 = percentiles(:,2);
yneg2 = abs(y2 - percentiles(:,1));
ypos2 = abs(y2 - percentiles(:,3));
% plot first error bars
e1 = errorbar(x-0.15,y1,yneg1,ypos1);
e1.LineWidth = error_bar_size;
% plot second error bars
e2 = errorbar(x+0.15,y2,yneg2,ypos2);
e2.LineWidth = error_bar_size;
% set axis limits and labels
xlim([0.5 4.5])
%%define ylimits manually to be symmetrical across x-axis
ylim(max(abs(ylim)).*[-1 1])
yline(0,'LineWidth',1)
xaxisproperties= get(gca, 'XAxis');
xaxisproperties.TickLabelInterpreter = 'latex';
xticks(x)
title(['subplot ',num2str(i)],'Interpreter','latex')
hold off
end
Nithin Kumar
on 24 Apr 2023
Edited: Nithin Kumar
on 24 Apr 2023
Hi Hung,
I understand that you are trying to create a plot consisting of 4 subplots arranged in a 2 by 2 grid and align the x-axes of the subplots on the same row, while preserving their Individual y-limits (Even though the Y- axes values are different, the subplot needs to look like the same for a visual reference).
Kindly refer the following code below to create the required plot.
% Generating example data
x1 = linspace(0, 10, 100);
y1 = sin(x1);
x2 = linspace(0, 10, 50);
y2 = cos(x2);
x3 = linspace(0, 10, 200);
y3 = exp(x3);
x4 = linspace(0, 10, 75);
y4 = tan(x4);
% Creating the figure and subplots
figure
subplot(2, 2, 1)
plot(x1, y1)
title('Subplot 1')
set(gca,'FontSize',12)
subplot(2, 2, 2)
plot(x2, y2)
title('Subplot 2')
set(gca,'FontSize',12)
subplot(2, 2, 3)
plot(x3, y3)
title('Subplot 3')
ylabel('y-axis label')
set(gca,'FontSize',12)
subplot(2, 2, 4)
plot(x4, y4)
title('Subplot 4')
set(gca,'FontSize',12)
% Adjusting the x-axis limits and tick marks
xlim([0 10])
set(gca, 'XTick', [0:2:10])
% Adjusting the y-axis limits for each subplot
ylim(gca, [min([y1 y2 y3 y4]) max([y1 y2 y3 y4])])
% Adjusting the size of each subplot to be the same
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1])
2 Comments
See Also
Categories
Find more on Line Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!