Using hold for multiple tiledlayout figures in a for loop.

조회 수: 108 (최근 30일)
Andrew Relyea
Andrew Relyea 2024년 3월 21일
댓글: Voss 2024년 3월 21일
I am building a post processor for batches of Monte-Carlo simulations with excessive amounts of data associated with each run, which prohibits loading/storing all of the data at once. I have a semi-functional code that uses subplot(3,1,x) to group like axis data, but my universal legend either covers portions of the data or skews one of the axes of one of the subplots. I know tiledlayout can make a common legend and place it such that it does not disrupt the figure or introduce excessive amounts of white space.
When I run this code
close all;clc
% data2 = figure();
% % data3 = figure();
t = 1:100;
d1a = randn(10,100);
d1b = randn(10,100);
d1c = randn(10,100);
data1 = figure();
tileddata1 = tiledlayout(3,1);
figure()
nexttile
for x = 1:10
tileddata1;
nexttile(1)
hold on
plot(t,d1a(x,:), 'b-')
hold off
nexttile(2)
hold on
plot(t,d1b(x,:),'b-')
hold off
nexttile(3)
hold on
b = plot(t,d1c(x,:),'b-');
hold off
end
tileddata1;
nexttile(1)
hold on
plot(t, mean(d1a,1),'r--')
hold off
nexttile(2)
hold on
plot(t, mean(d1b,1),'r--')
hold off
nexttile(3)
hold on
r = plot(t,mean(d1c,1),'r--');
xlabel('Time')
leg = legend([b,r],'data','E[data]','Orientation','horizontal');
leg.Layout.Tile = 'south';
I get the intended result, though here it looks like my plot was reformatted to save space. But when I try to add an independent figure utilizing different code
t = 1:100;
d1a = randn(10,100);
d1b = randn(10,100);
d1c = randn(10,100);
data1 = figure();
tileddata1 = tiledlayout(3,1);
nexttile
figure()
tileddata2 = tiledlayout(3,1,"TileSpacing","tight");
nexttile
d2a = randn(10,100);
d2b = randn(10,100);
d2c = randn(10,100);
for x = 1:10
tileddata1;
nexttile(1)
hold on
plot(t,d1a(x,:), 'b-')
hold off
nexttile(2)
hold on
plot(t,d1b(x,:),'b-')
hold off
nexttile(3)
hold on
b = plot(t,d1c(x,:),'b-');
hold off
tileddata2;
nexttile(1)
hold on
plot(t,d2a(x,:))
hold off
nexttile(2)
hold on
plot(t,d2b(x,:))
hold off
nexttile(3)
hold on
b = plot(t,d2c(x,:));
hold off
end
tileddata1;
nexttile(1)
hold on
plot(t, mean(d1a,1),'r--')
hold off
nexttile(2)
hold on
plot(t, mean(d1b,1),'r--')
hold off
nexttile(3)
hold on
r = plot(t,mean(d1c,1),'r--');
xlabel('Time')
leg = legend([b,r],'data','E[data]','Orientation','horizontal');
leg.Layout.Tile = 'south';
All the data gets thrown into the second figure. I need to maintain separation of my data.

채택된 답변

Voss
Voss 2024년 3월 21일
편집: Voss 2024년 3월 21일
Specify which tiledlayout you want to use by passing it as the first input to nexttile.
Example of plotting to two figures with tiledlayouts simultaneously:
t = 1:100;
d1a = randn(10,100);
d1b = randn(10,100);
d1c = randn(10,100);
d2a = randn(10,100);
d2b = randn(10,100);
d2c = randn(10,100);
f1 = figure();
t1 = tiledlayout(3,1);
f2 = figure();
t2 = tiledlayout(3,1,"TileSpacing","tight");
for x = 1:10
nexttile(t1,1)
hold on
plot(t,d1a(x,:), 'b-')
hold off
nexttile(t1,2)
hold on
plot(t,d1b(x,:),'b-')
hold off
nexttile(t1,3)
hold on
b = plot(t,d1c(x,:),'b-');
hold off
nexttile(t2,1)
hold on
plot(t,d2a(x,:))
hold off
nexttile(t2,2)
hold on
plot(t,d2b(x,:))
hold off
nexttile(t2,3)
hold on
b = plot(t,d2c(x,:));
hold off
end
nexttile(t1,1)
hold on
plot(t, mean(d1a,1),'r--')
hold off
nexttile(t1,2)
hold on
plot(t, mean(d1b,1),'r--')
hold off
nexttile(t1,3)
hold on
r = plot(t,mean(d1c,1),'r--');
xlabel('Time')
leg = legend([b,r],'data','E[data]','Orientation','horizontal');
leg.Layout.Tile = 'south';
(I'm not sure what the intent is for the legend, because b and r are lines in two different tiledlayouts.)
  댓글 수: 2
Andrew Relyea
Andrew Relyea 2024년 3월 21일
@Voss Thanks. This was exactly what I needed. I was operating under the assumption that the tiledlayout handle was equivalent to a figure handle. My plots are looking great now.
Voss
Voss 2024년 3월 21일
You're welcome!

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Taylor
Taylor 2024년 3월 21일
It always helps to be explicit with your figure and axis handles. Also, the for loops were unecessary. Hope this is more what you're looking for!
t = 1:100;
d1a = randn(10, 100);
d1b = randn(10, 100);
d1c = randn(10, 100);
tileddata1 = tiledlayout(3, 1);
d2a = randn(10, 100);
d2b = randn(10, 100);
d2c = randn(10, 100);
ax11 = nexttile(tileddata1, 1);
hold(ax11, "on")
plot(ax11, t, d1a, 'b-')
plot(ax11, t, mean(d1a, 1), 'r--')
hold(ax11, "off")
ax12 = nexttile(tileddata1, 2);
hold(ax12, "on")
plot(ax12, t, d1b,'b-')
plot(ax12, t, mean(d1b, 1), 'r--')
hold(ax12, "off")
ax13 = nexttile(tileddata1, 3);
hold(ax13, "on")
b = plot(ax13, t, d1c, 'b-');
r = plot(ax13, t, mean(d1c, 1), 'r--');
hold(ax13, "off")
leg = legend([b(1), r], {'data', 'E[data]'}, 'Orientation', 'horizontal');
leg.Layout.Tile = 'south';
xlabel(ax13, 'Time')
figure;
tileddata2 = tiledlayout(3, 1, "TileSpacing", "tight");
ax21 = nexttile(tileddata2, 1);
plot(ax21, t, d2a)
ax22 = nexttile(tileddata2, 2);
plot(ax22, t, d2b)
ax23 = nexttile(tileddata2, 3);
b = plot(ax23, t, d2c);
  댓글 수: 1
Andrew Relyea
Andrew Relyea 2024년 3월 21일
@Taylor, This is a sample data set just used to help me get the concept across. My actual data is pre-release and can't be used published here. The for loop is used to bring in the data from a single run out of the batch (in this case one row of each array represents the data for that variable in that run).

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Specifying Target for Graphics Output에 대해 자세히 알아보기

제품


릴리스

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by