How to dynamically change name of table?
14 views (last 30 days)
Show older comments
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
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:
https://www.mathworks.com/help/matlab/matlab_prog/grouped-calculations-in-tables-and-timetables.html
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:
Accepted Answer
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)
% 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
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)
% collect groups of data
[G,GID] = findgroups(T.Var2);
F = @(varargin){table(varargin{:})};
C = splitapply(F,T,G)
C{1} % group 1 data
% 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.
More Answers (0)
See Also
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!