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

1 view (last 30 days)
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.
  1 Comment
Stephen23
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.

Sign in to comment.

Accepted Answer

Stephen23
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.
  3 Comments
Stephen23
Stephen23 on 13 Oct 2015
Edited: Stephen23 on 13 Oct 2015
My pleasure.
I see that you are still using the code from my earlier answer, even though you have not accepted it. It is considered polite to accept answers on this forum: we volunteer our time to help you, and accepting is a small sign of appreciation from you :)
Here are some small changes that should give you want you are looking for. Firstly we can create the matrix B from A without that ugly concatenation, and you should probably use ceil instead of round:
B = A.data(:,[2,11,14,28]);
D = 0:ceil(max(B(:,4)));
and to create the colormap with the size that you require, try this:
V = 2:5:numel(D);
set(0,'DefaultAxesColorOrder',winter(numel(V)));
for k = V
... etc
Note that I got rid of col as this is not needed: you do not need to call colormap at the end of your code: the colormap has already been set by the line set(0,'DefaultAxesColorOrder'.... You can pick either of these methods, but you do not need to do both.
Avoid using the colormap jet, it is a truly awful colormap, which is explained here:
aaron Harvey
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.

Sign in to comment.

More Answers (1)

Eng. Fredius Magige
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
  1 Comment
aaron Harvey
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.

Sign in to comment.

Categories

Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!