Index exceeded matrix dimensions

I am trying to create 12 windroses for each month of a year using data in the workspace (variable but around 720 by 24 tables) and each time I try to run the code below I get the index exceeded error message. I have managed to get the windrose figure for one month but wanted to automate the process with a for loop, suggestions.
nFiles = 12;
for i = 1:nFiles
filename = sprintf('%s_%d', 'Month', i);
Options = {'anglenorth', 0, 'angleeast', 90, 'labels', {'North (0)', 'South (180)', 'East (90)', 'West (270)'}, 'Min_Radius', .05, 'nFreq', 8, 'FreqRound', 3, 'freqlabelangle', 45, 'cMap','invparula' 'vWinds', [0 5 5 10 10 15 15 20 20 25 25 30 30 35 35 40], 'TitleString',{'January';''},'LabLegend','Wind Speed in km/h', 'TitleFontWeight', 'bold', 'LegendType', 2};
[figure_handle, count, Speeds, Directions, Table] = WindRose(filename(:,12) .* 10, filename(:,14), Options);
end

5 Comments

Why are you taking column 12 of the file name itself?
I am trying to access column 12 of the workspace tables Month_1 to month_12, there is most likely an error in my approach.
Stephen23
Stephen23 on 23 May 2018
Edited: Stephen23 on 23 May 2018
"...there is most likely an error in my approach."
Yes, there is. Accessing variable names dynamically using eval, assignin, etc. is slow, complex, buggy and hard to debug. Beginners think that they will write great code using eval, but actually they just force themselves into writing slow, complex, buggy code. The MATLAB documentation specifically advises against what you are trying to do: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store related data in a single array"
There are many good reasons to avoid using eval to dynamically access variable names, some of them are explained here:
Note that putting 1, 2, ... 12 into the variable names means that you have used pseudo indexing, which could trivially be turned into real indexing: thus you could easily write more efficient code.
Advice to use eval is teaching you how to write slow, complex code which is ahrd to debug. If you want to write simpler, more efficient code which is much easier to read, write, and debug, then put your data into one array and use indexing.
I have seen as much but how would I convert (not literal, just keep the same result) this way using eval to a more efficient method?
nFiles = 12;
for i = 1:nFiles
filename = sprintf('%s_%d', 'Month', i);
Options = {'anglenorth', 0, 'angleeast', 90, 'labels', {'North (0)', 'South (180)', 'East (90)', 'West (270)'}, 'Min_Radius', .05, 'nFreq', 8, 'FreqRound', 3, 'freqlabelangle', 45, 'cMap','invparula' 'vWinds', [0 5 5 10 10 15 15 20 20 25 25 30 30 35 35 40], 'TitleString',{'January';''},'LabLegend','Wind Speed in km/h', 'TitleFontWeight', 'bold', 'LegendType', 2};
[figure_handle, count, Speeds, Directions, Table] = WindRose(eval([filename,'{:,12} .* 10']), eval([filename,'{:,14}']), Options);
end
@Cameron Power: the problem is not eval in itself, it is how beginners access variable names dynamically. The same problems occur regardless of what function or method is used to access the variable names dynamically. So, the best advice you will get is to avoid this situation entirely, which is trivial to do using one variable and indexing, exactly like the MATLAB documentation and all MATLAB experts recommend.
Read the links that I gave you, you can learn why this is a bad practice, and how simple the (much better) alternatives are.

Sign in to comment.

 Accepted Answer

Majid Farzaneh
Majid Farzaneh on 23 May 2018
Edited: Majid Farzaneh on 24 May 2018
Hi,
[filename = sprintf('%s%d', 'Month', i);]_ makes a string like this: Month_1
Then you have used filename(:,12) and filename(:,14) . It means you want 12th or 14th character in the string that it's not exist. for example Month_1 has 7 characters and filename length is 7. So for 12 and 14 you have the error "Index exceeded matrix dimensions".

5 Comments

If Month_1 to Month_12 are defined in workspace you can use eval to consider the string as a command.
[figure_handle, count, Speeds, Directions, Table] = WindRose(eval([filename,'(:,12) .* 10']), eval([filename,'(:,14)']), Options);
When using the code specified it returned this error
Error using eval Undefined function 'times' for input arguments of type 'table'.
times (.*) is not defined for table class. You should convert table to array first, then use times. You can use this:
eval(['array=table2array(',filename,');']);
[figure_handle, count, Speeds, Directions, Table] = WindRose(array(:,12) .* 10), array(:,14)), Options);
I figured it out using eval, I changed to curly brackets and it worked normally, thank you.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!