How to dynamically change name of table?

조회 수: 14 (최근 30일)
Marina
Marina 2024년 4월 10일
댓글: Voss 2024년 4월 11일
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
Stephen23
Stephen23 2024년 4월 10일
편집: Stephen23 2024년 4월 10일
"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 2024년 4월 10일
Thank you for all the links!

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

채택된 답변

Voss
Voss 2024년 4월 10일
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
Voss
Voss 2024년 4월 11일
You're welcome!
Voss
Voss 2024년 4월 11일
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.

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

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Tables에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by