How do you plot two graphs with multiple curves next to a table?

9 views (last 30 days)
I have essentially a multi-dimensional table. Because I don't know a better way, I have chosen to put it all in one table with blanks to portray the idea of another dimension (see image of table below). My goal is to show this table next to two graphs that have a lot of the same information contained. I have been able to get those two pieces separately, but can't find how to put them all in one screen.
The input data is subject to change, including the number of speed elements, number of deployment elements, etc.
I have tried wrapping my head around the difference between "tiledlayout", "subplots", and "uifigure/uitable/etc." and attempted this multiple different ways with no success.
Here is my current example code. Not the exact code I am working with but very similar:
z
% Input data
Speeds = [40,80,120];
ExampleData = strings(9,5);
ExampleData(:,3:end) = rand(9,3);
for n = 1:length(Speeds)
ExampleData(n+(2*(n-1)),1) = Speeds(n);
ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,2) = ([5;10;15]);
end
% Create table
Headings = ["Speed" "Deployment" "Drag" "Lift" "Strain"];
DataTable = array2table(ExampleData,'VariableNames',Headings);
fig = uifigure;
uit = uitable(fig,"Data",DataTable);
% Color missing elements red
styleIndices = ismissing(DataTable);
[row,col] = find(styleIndices);
s = uistyle("BackgroundColor",[1 0.6 0.6]);
addStyle(uit,s,"cell",[row,col]);
% Create graph for drag
tiledlayout(2,2)
nexttile(2)
title("Avg Drag")
xlabel("Deployment")
xticks([5,10,15])
hold on
for n = 1:length(Speeds)
plot([5 10 15],double(ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,3)))
end
hold off
% Create graph for lift
nexttile(4)
title("Avg Drag")
xlabel("Deployment")
xticks([5,10,15])
hold on
for n = 1:length(Speeds)
plot([5 10 15],double(ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,4)))
end
hold off
Here is what it displays:
Here is what I want it to display (doctored photo):
Is this possible to achieve?
I am also open to any advice on restructuring this more efficiently! Thanks in advance!

Accepted Answer

Adam Danz
Adam Danz on 30 Mar 2023
Edited: Adam Danz on 30 Mar 2023
Create a uigridlayout and put a uitable in it using the Layout property of uitable. To add the axes in the demo below, I added a uipanel on the right (invisible) and then I used tiledlayout() to add two axes that are within the uipanel.
Adjust the demo to your needs. I've added comments where you can tweek the sizes of each object within the grid.
T = table(randi(100,10,1),randi(5,10,1),rand(10,1),rand(10,1), ...
'VariableNames', {'Speed','Deployment','Drag','Lift'});
fig = uifigure();
uig = uigridlayout(fig,[1,4]); %create a 1x4 grid
uit = uitable(uig,'data',T);
uit.Layout.Row = 1;
uit.Layout.Column = [1,3]; % Uitable goes in the first 3 columns of the grid
uip = uipanel(uig,'BorderType','None');
uip.Layout.Row = 1;
uip.Layout.Column = 4; % uipanel goes in the 4th column.
tcl = tiledlayout(uip,2,1); % TileChartLayout goes in the uipanel, size 2x1
ax1 = nexttile(tcl); % Add a tile (axes) to the TiledChartLayout
plot(ax1, T.Deployment, T.Drag,'o')
title(ax1,'Drag')
xlabel(ax1,'Deployment')
box(ax1,'on')
ax2 = nexttile(tcl); % Add a tile (axes) to the TiledChartLayout
plot(ax2, T.Deployment, T.Lift,'o')
title(ax2,'Lift')
xlabel(ax2,'Deployment')
box(ax2,'on')
  2 Comments
Mathew
Mathew on 30 Mar 2023
Much appreciated! For anyone who may reference in the future, one other ticket that I had to find was using hold(ax1,'on') instead of hold on to get multiple curves with a for loop, rather than plotted points. I guess it is good practice to be more specific with your holds. Here is the final code I was able to achieve with Adam's help:
% Input data
Speeds = {'40' '80' '120'};
ExampleData = strings(9,5);
ExampleData(:,3:end) = rand(9,3);
for n = 1:length(Speeds)
ExampleData(n+(2*(n-1)),1) = str2double(Speeds(n));
ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,2) = ([5;10;15]);
end
% Create table
Headings = ["Speed" "Deployment" "Drag" "Lift" "Strain"];
DataTable = array2table(ExampleData,'VariableNames',Headings);
fig = uifigure();
uig = uigridlayout(fig,[1,4]); %create a 1x4 grid
uig.ColumnWidth = {200,200,200,900};
uit = uitable(uig,'data',DataTable);
uit.Layout.Row = 1;
uit.Layout.Column = [1,3]; % Uitable goes in the first 3 columns of the grid
uip = uipanel(uig,'BorderType','None');
uip.Layout.Row = 1;
uip.Layout.Column = 4; % uipanel goes in the 4th column.
tcl = tiledlayout(uip,2,1); % TileChartLayout goes in the uipanel, size 2x1
ax1 = nexttile(tcl); % Add a tile (axes) to the TiledChartLayout
title(ax1,"Avg Drag")
xlabel(ax1,"Deployment")
xticks(ax1,[5,10,15])
hold(ax1,'on')
for n = 1:length(Speeds)
plot(ax1,[5 10 15],double(ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,3)))
end
hold(ax1,'off')
title(ax1,'Drag')
xlabel(ax1,'Deployment')
box(ax1,'on')
legend(ax1,{'5','10','15'})
ax2 = nexttile(tcl); % Add a tile (axes) to the TiledChartLayout
hold(ax2,'on')
for n = 1:length(Speeds)
plot(ax2,[5 10 15],double(ExampleData(n+(2*(n-1)):n+(2*(n-1))+2,4)))
end
hold(ax2,'off')
title(ax2,'Lift')
xlabel(ax2,'Deployment')
box(ax2,'on')
Adam Danz
Adam Danz on 30 Mar 2023
> it is good practice to be more specific with your holds
💯
Indeed! Thanks for pointing that out. You may have noticed that I specified parent handles in all of the graphics functions in my solution such as title(ax1,__), uipanel(uig,__). I think it's more readable and it eliminate the possibility of objects being applied to the wrong parent.

Sign in to comment.

More Answers (1)

Peter Perkins
Peter Perkins on 5 Apr 2023
Edited: Peter Perkins on 5 Apr 2023
Mathew, I think you are making your life more difficult than it needs to be with all those strings. I get that you are trying to have a nice display for each speed, but it's making the computations pretty awkward, I think. You might be better off making your own pretty-print function just for display. In any case, with numeric variables:
speeds = [40 80 120];
Speed = repelem(speeds(:),3);
Drag = rand(9,1);
Lift = rand(9,1);
Strain = rand(9,1);
Deployment = repmat([5;10;15],3,1);
T = table(Speed,Deployment,Drag,Lift,Strain)
for sp = speeds
plot(T(T.Speed == sp,:),"Deployment","Drag");
hold on
end
hold off
I don't know if this helps at all, but variables in a table can have multiple columns, so this might be another way to see both your dimensions:
>> Deployment = Deployment(1:3);
>> Drag = reshape(Drag,3,3);
>> Lift = reshape(Lift,3,3);
>> Strain = reshape(Strain,3,3);
>> T = table(Deployment,Drag,Lift,Strain)
T =
3×4 table
Deployment Drag Lift Strain
__________ _____________________________ _____________________________ _______________________________
5 0.22592 0.4357 0.43021 0.97975 0.25806 0.26221 0.22175 0.31878 0.085516
10 0.17071 0.3111 0.18482 0.43887 0.40872 0.60284 0.11742 0.42417 0.26248
15 0.22766 0.92338 0.90488 0.11112 0.5949 0.71122 0.29668 0.50786 0.80101

Categories

Find more on Specifying Target for Graphics Output in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!