How to dynamically change name of table?

14 views (last 30 days)
Marina
Marina on 10 Apr 2024
Commented: Voss on 11 Apr 2024
This code below is just a very simple example of some analysis I am doing with my experimental results.
I am running 5 cycles of an experiment, results come out in a long txt file, I want to plot everything with a different color based on cycle number. So I am creating sub-tables from the main table based on the parameter of interest. This simple code works parfectly. However, it's fine because it is only 5 runs. What if it was 100?
Is there a more efficient way to assign table names dynamically? I am new with Matlab and I am using my real life needs to practice and learn.
Thank you!
T=readtable("Output-C1_Cu.txt","NumHeaderLines",2);
NT1=T(T.Var2==1,:);
NT2=T(T.Var2==2,:);
NT3=T(T.Var2==3,:);
NT4=T(T.Var2==4,:);
NT5=T(T.Var2==5,:);
plot(NT1,"Var4","Var6",LineWidth=1.5, Color=[0 0.4470 0.7410])
hold on
plot(NT2,"Var4","Var6",LineWidth=1.5, Color=[0.8500 0.3250 0.0980])
hold on
plot(NT3,"Var4","Var6",LineWidth=1.5, Color=[0.9290 0.6940 0.1250])
hold on
plot(NT4,"Var4","Var6",LineWidth=1.5, Color=[0.4940 0.1840 0.5560])
hold on
plot(NT5,"Var4","Var6",LineWidth=1.5, Color=[0.4660 0.6740 0.1880])
hold off
xlim([0,1.5])
xlabel('V cell (V)','FontWeight','bold')
ylabel("dQ/dV cell (mAh/V)","FontWeight","bold")
title('Treated Cu - OG Si')
legend({'Cycle 1','Cycle 2','Cycle 3','Cycle 4','Cycle 5',}, ...
'Location','southeast')
  2 Comments
Stephen23
Stephen23 on 10 Apr 2024
Edited: Stephen23 on 10 Apr 2024
"Is there a more efficient way to assign table names dynamically? "
No, there is not. Every way is slow, inefficient, complex, and pointlessly obfuscates code:
MATLAB is designed around arrays and indexing. Indexing is exactly how you would handle "What if it was 100?", because indexing trivially expands to any size (hint: try using a loop). Indexing is exactly how experienced MATLAB users would do it, or by using the inbuilt tools for processing groups of data:
Your approach of copy-pasting lots of code or dynamically naming variables ... is best avoided.
"I am new with Matlab and I am using my real life needs to practice and learn."
Then forget about dynamic variable names. That is a path you really don't want to go down:
Marina
Marina on 10 Apr 2024
Thank you for all the links!

Sign in to comment.

Accepted Answer

Voss
Voss on 10 Apr 2024
One way to plot the table data for each cycle separately, without having to create a new table variable for each cycle, is to use findgroups and splitapply.
% make up a table
Var = randi([1,10],40,6);
Var(:,4) = Var(:,4)/10;
T = array2table(Var)
T = 40x6 table
Var1 Var2 Var3 Var4 Var5 Var6 ____ ____ ____ ____ ____ ____ 7 10 3 0.1 6 9 2 5 9 0.4 8 1 9 8 8 0.6 8 8 8 9 6 0.6 9 7 7 3 1 0.4 2 8 5 8 7 0.5 4 2 8 9 7 1 3 5 1 9 9 0.9 5 2 7 4 8 0.6 4 2 7 4 2 0.9 1 6 10 9 6 0.2 5 5 8 1 2 0.9 9 2 8 2 9 0.6 6 8 10 6 7 0.9 1 1 10 7 2 0.9 3 4 5 5 6 0.3 10 10
% plot Var6 vs Var4 separately for each Var2 group
figure
hold on
[G,GID] = findgroups(T.Var2);
F = @(varargin)plot(varargin{4},varargin{6},LineWidth=1.5);
splitapply(F,T,G)
hold off
xlim([0,1.5])
xlabel('V cell (V)','FontWeight','bold')
ylabel("dQ/dV cell (mAh/V)","FontWeight","bold")
title('Treated Cu - OG Si')
legend("Cycle "+GID,'Location','southeast')
Also running your code to plot the first 5 groups, for comparison/validation:
NT1=T(T.Var2==1,:);
NT2=T(T.Var2==2,:);
NT3=T(T.Var2==3,:);
NT4=T(T.Var2==4,:);
NT5=T(T.Var2==5,:);
figure
hold on
plot(NT1,"Var4","Var6",LineWidth=1.5, Color=[0 0.4470 0.7410])
plot(NT2,"Var4","Var6",LineWidth=1.5, Color=[0.8500 0.3250 0.0980])
plot(NT3,"Var4","Var6",LineWidth=1.5, Color=[0.9290 0.6940 0.1250])
plot(NT4,"Var4","Var6",LineWidth=1.5, Color=[0.4940 0.1840 0.5560])
plot(NT5,"Var4","Var6",LineWidth=1.5, Color=[0.4660 0.6740 0.1880])
hold off
xlim([0,1.5])
xlabel('V cell (V)','FontWeight','bold')
ylabel("dQ/dV cell (mAh/V)","FontWeight","bold")
title('Treated Cu - OG Si')
legend({'Cycle 1','Cycle 2','Cycle 3','Cycle 4','Cycle 5',}, ...
'Location','southeast')
  9 Comments
Voss
Voss on 11 Apr 2024
By the way, it may be convenient to collect each groups' data together, into say a cell array of tables, rather than just plotting it directly. Then you can plot it afterward or do whatever else you need to do on a group-by-group basis. Here's one way of doing that:
% make up a table
Var = randi([1,10],40,6);
Var(:,4) = Var(:,4)/10;
T = array2table(Var)
T = 40x6 table
Var1 Var2 Var3 Var4 Var5 Var6 ____ ____ ____ ____ ____ ____ 8 8 4 1 10 5 8 5 10 0.2 5 6 8 3 6 0.8 7 6 7 7 3 0.3 10 3 10 9 6 0.9 10 1 2 9 8 0.5 6 7 2 10 2 0.1 4 6 5 7 3 0.9 7 3 4 8 4 0.7 8 4 7 6 5 0.1 10 5 7 6 7 0.3 7 10 8 5 1 0.6 6 10 6 6 7 0.5 4 5 4 4 1 0.1 8 2 8 1 5 0.7 5 3 7 6 1 0.8 9 8
% collect groups of data
[G,GID] = findgroups(T.Var2);
F = @(varargin){table(varargin{:})};
C = splitapply(F,T,G)
C = 10x1 cell array
{4x6 table} {3x6 table} {6x6 table} {2x6 table} {6x6 table} {6x6 table} {3x6 table} {4x6 table} {4x6 table} {2x6 table}
C{1} % group 1 data
ans = 4x6 table
Var1 Var2 Var3 Var4 Var5 Var6 ____ ____ ____ ____ ____ ____ 8 1 5 0.7 5 3 2 1 2 0.6 8 7 2 1 10 0.8 9 7 10 1 6 0.3 4 7
% plot Var6 vs Var4 separately for each Var2 group
figure
hold on
for ii = 1:numel(C)
plot(C{ii}.Var4,C{ii}.Var6,LineWidth=1.5)
end
hold off
xlim([0,1.5])
xlabel('V cell (V)','FontWeight','bold')
ylabel("dQ/dV cell (mAh/V)","FontWeight","bold")
title('Treated Cu - OG Si')
legend("Cycle "+GID,'Location','southeast')
Here the anonymous function F
F = @(varargin){table(varargin{:})};
makes a cell array containing one table of data. Then (as before) splitapply runs that function for each group, so you get C, a cell array containing a table of data for each group.

Sign in to comment.

More Answers (0)

Categories

Find more on Tables in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!