Creating legend in loop for multiple figures

I have a directory of .mat files containing data from multiple days on each of multiple treatments of an experiment. I am graphing all data from each treatment on a different graph (i.e. multiple days of data on each figure but only the same treatment). I have a cell array with an ID for each dataset containing the day-of-year (DOY) and treatment number (i.e. 152T1). The files are called in order of treatment (and day-of-year within treatment), so ideally I could specify for each figure that the legend contains the range of strings for anything containing "T1" (or whatever treatment) and this would generate the strings identifying the day-of-year for that treatment.
If there were only 2 or 3 treatments, I would manually create a distinct cell array for each treatment containing the DOYs for that treatment, but there are about 130 different treatments, so I would like to figure out a way to do this automatically within the loop.
One way that I could think of (but haven't implemented because I feel there should be something easier) is to 'fill out' a new cell array for each treatment within the loop containing the identifier for the data (using eval to figure out which cell array the data belongs to) and then just call the pertinent cell array of DOYs for each treatment in the legend, but this still leaves the issue of creating each and every cell array manually outside of the loop to avoid calling an undefined variable on the first iteration of each treatment.
Does this make sense?

6 Comments

You need to provide an abstract of the problem without overwhelming details. Let's say there are only 2 or 3 treatments, how do you manually create the legend? Then explain which part do you want to be automated.
%I have this already:
IDs = {'142T1','169T1','173T1','136T2','148T2','92T3','183T3','198T3'}
% So if I did it manually, I would create something like this outside of the loop
T1 = {'142', '169', '173'}
T2 = {'136','148'}
T3 = {'92','183','198'}
for i = 1:lengthdirectory
Treatment = str2double(T)
%where T is pulled from the ID{i}
figure(T)
plot(data)
end
figure(1); legend(T1);
figure(2); legend(T2);
figure(3); legend(T3);
It would be nice to be able to do something like
figure(1)
legend(ID(........))
where the '.......' would say use only the cells where the 5th component of the string is '1' (i.e. treatment 1).'
Does this clear it up or make it more confusing?
So is it that you want to separate
IDs = {'142T1','169T1','173T1','136T2','148T2','92T3','183T3','198T3'}
into 3 groups?
Group1={'142T1','169T1','173T1'}
Group2={'136T2','148T2'}
Group3={'92T3','183T3','198T3'}
The criteria of the grouping is that they have the same treatment number?
Yes, the criteria of the grouping is that they have the same treatment 'number'.
This was my 'best guess' below... a loop that ran after the graphing loop was done. The main problem is that because I am using the iteration# from the loop to index within the different cells (named by the treatment name), I have a bunch of empty cells in anything beyond the 1st cell created which causes problems when using them for the legend so I would need some function or way to delete any empty cells from the cell array. The reason I am using the iteration# is because I am not predeclaring the cells prior to the loop (LOTS of them), so something like Treat{end+1} = '178'; would not work to initiate the variable. So if I could find a way to clear out empty cells from something that currently looks like:
Treat1 = {[] [] [] [] [] '136' '153' '173'}
then I could just call each independent cell to put a legend in the figure using the eval command.
for i = 1:length(ID)
%my IDs are in the format 10311P1T1_xxxxx where 103-11 is DOY-Yr, Plot 1, %Tree 1 _ and then some other information.
idx1 = strfind(ID{i},'_');
which = ID{i}(6:idx1-1);
eval([which,'{i} = ',ID{i}(1:3)])
%I numbered my figures according to plot/tree with three 000s in between
fignum = str2double([ID{i}(7),'000',ID{i}(9:idx1-1)]);
eval(['figure(',fignum,'); legend(',which,');'])
end
I can't help you if you change your story now and then. Your previous ID is '142T1', now it's '10311P1T1_xxxxx'. Your previous plot number is figure(T), now it's figure(P000T). I'll update my code below later.
To remove empty cells.
Treat1 = {[] [] [] [] [] '136' '153' '173'};
Treat1=Treat1(~cellfun(@isempty,Treat1))
Treat1 =
'136' '153' '173'

Sign in to comment.

Answers (2)

IDs = {'142T1','169T1','173T1','136T2','148T2','92T3','183T3','198T3'};
Treats=regexp(IDs,'T.+','match');
Treats=cellfun(@char,Treats,'uni',0);
[UniTreats,Index,RevIndex]=unique(Treats);
N_UniTreats=length(UniTreats);
LegendData=cell(N_UniTreats,1);
for k=1:N_UniTreats
LegendData{k}=IDs(RevIndex==k);
end
UniTreats
LegendData{:}
UniTreats =
'T1' 'T2' 'T3'
ans =
'142T1' '169T1' '173T1'
ans =
'136T2' '148T2'
ans =
'92T3' '183T3' '198T3'
I will just provide this function to see if you can utilize it to help you complete your task. Save the following code in to a parse_id.m file.
function [DateNumber,P_Number,T_Number,Extra]=parse_id(String)
Temp=regexp(String,'\d+','match');
[DateNumber,P_Number,T_Number]=deal(Temp{1:3});
Temp=regexp(String,'_.+','match');
Extra=Temp{1}(2:end);
>> [DateNumber,P_Number,T_Number,Extra]=parse_id('10311P1T1_123abcxxxxx_jlkj')
DateNumber =
10311
P_Number =
1
T_Number =
1
Extra =
123abcxxxxx_jlkj
Then you can do FigureNumber=[P_Number,'000',T_Number].
To process IDs in a cell array, use cellfun()
[a,b,c,d]=cellfun(@parse_id,{'10311P1T1_123abcxxxxx_jlkj','13011P2T3_xyz123'},'uni',0)
a =
'10311' '13011'
b =
'1' '2'
c =
'1' '3'
d =
'123abcxxxxx_jlkj' 'xyz123'

Tags

Asked:

on 1 Jul 2011

Community Treasure Hunt

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

Start Hunting!