# Plotting in for loop not working. Averaging matrix over ranges.

1 view (last 30 days)
aaron Harvey on 13 Oct 2015
Edited: aaron Harvey on 13 Oct 2015
I thought i had a code that worked but i noticed a tiny error, and ive been banging my head on a brick wall sleeplessly trying to get it to work for days.
Heres my code, i hate it, it doesn't work, if you reckon you can fix it please tell me otherwise just skip this bit and as I've decide to start again.
function TempSalplot(datafile)
datafile=importdata(datafile);
A=datafile.data;
figure;
col = flipud(parula(round(max(datafile.data(:,28)))));
%depth,distance,salinity,temp are in column 28,2,14,11 of datafile respectively;
for d=[1:3:max(datafile.data(:,28))]; %max is around 16
for avd=[1:length(A(:,28))];
if A(avd,28)>d-0.5 & A(avd,28)<d+0.5;
B(avd,1)=A(avd,2);
B(avd,2)=A(avd,14);
B(avd,3)=A(avd,11);
B(all(B==0,2),:)=[];
end
[M,~,z] = unique(B(:,1),'stable');
M(:,2) = accumarray(z,B(:,2),[],@mean);
M(:,3) = accumarray(z,B(:,3),[],@mean);
plot(M(:,2),M(:,3),'o-','color',col(d,:));
hold on;
end
xlabel('Salinity (psu)');
ylabel('Tempurature (degC)');
h=colorbar('ticks',[1:3:round(max(datafile.data(:,28)))]);
h.Label.String=('Depth (m)');
caxis([1,max(d)]);
colormap(col);
end
Essentially i have 4 columns of interest say (a,b,c,d). I would like to average b and c over certain ranges of d. so I would only have as many b,c pairs for a certain d range as there are a values. Then I would like to plot that and redo it for another a range.
data=
0 15 33 0.5
0 15 32 0.8
0 16 32 1.3
0 13 34 1.6
10 13 34 0.6
10 14 35 1.0
10 16 36 1.5
10 12 33 1.9
25 13 34 0.6
25 12 33 0.9
25 12 34 1.6
25 12 36 1.9
What I think I need is a for loop.
1st iteration for 0<d=<1 (d=0.5).
M=
0 15 32.5 0.5
10 13.5 34.5 0.5
25 12.5 33.5 0.5
plot(M(:,2),M(:,3));
then repeat for d=1.5 (1<d=<2) however some of the later iteration for example (10<d=<11) have no measurements for certain values of a so should be shorter than the earlier iterations and therefore plot fewer points.
Any help on this is really appreciated , this has been a nightmare for me, thinking I had it working so many times.
Stephen23 on 13 Oct 2015
I notice that you are using my solution to your earlier question:
[M,~,z] = unique(B(:,1),'stable');
M(:,2) = accumarray(z,B(:,2),[],@mean);
M(:,3) = accumarray(z,B(:,3),[],@mean);
and yet you have not accepted my answer to that question.

Stephen23 on 13 Oct 2015
Edited: Stephen23 on 13 Oct 2015
It is easy to split your data into groups according to the fourth column:
B = [...
0 15 33 0.5
0 15 32 0.8
0 16 32 1.3
0 13 34 1.6
10 13 34 0.6
10 14 35 1.0
10 16 36 1.5
10 12 33 1.9
25 13 34 0.6
25 12 33 0.9
25 12 34 1.6
25 12 36 1.9];
% Vector of the edges of each group:
D = 0:2;
% Set figure colormap befor the loop:
set(0,'DefaultAxesColorOrder',winter(numel(D)-1))
% Iterate over each group:
for k = 2:numel(D)
% Logical index for this group:
X = D(k-1)<B(:,4) & B(:,4)<=D(k);
% Calculate means for this group:
[M,~,z] = unique(B(X,1));
M(:,4) = accumarray(z,B(X,4),[],@mean);
M(:,3) = accumarray(z,B(X,3),[],@mean);
M(:,2) = accumarray(z,B(X,2),[],@mean);
% Display info (optional):
fprintf('From %d to %d\n',D(k-1),D(k))
disp(M)
% Plot:
plot(M(:,2),M(:,3))
hold all
end
which displays this in the command window:
From 0 to 1
0.00000 15.00000 32.50000 0.65000
10.00000 13.50000 34.50000 0.80000
25.00000 12.50000 33.50000 0.75000
From 1 to 2
0.00000 14.50000 33.00000 1.45000
10.00000 14.00000 34.50000 1.70000
25.00000 12.00000 35.00000 1.75000
And creates this figure:
Note that I do not have the colormap parula, so I used winter instead.
aaron Harvey on 13 Oct 2015
Edited: aaron Harvey on 13 Oct 2015
Perfect! first method worked a treat. I didn't fully realise accepting and up voting weren't the same thing, I definitely 100% accept this answer!! Its not just fixed the code but taught me what the fix was too. You have helped a panicing student claw back a huge chunk of his final project.

Eng. Fredius Magige on 13 Oct 2015
Hi You might review few lines, specially for and if, as to be:
for d=1:3:max(datafile.data(:,28)) %max is around 16 for avd=1:length(A(:,28)) if (d<A(avd,28)+0.5 && d>A(avd,28)-0.5)
try it
aaron Harvey on 13 Oct 2015
Edited: aaron Harvey on 13 Oct 2015
unfortunately no that didn't work. The vairable B is not being found outside the if function? but I'm not sure my nested for and ifs work anyway.