Reputation: 1326
There are three curves in a plot and I am not able to find the peaks of these three curves.
How to go about finding the peaks?
The below is the (x,y)
values.
>> [x,y]
ans =
1 86
5 91
8 94
12 98
15 101
19 103
21 104
23 105
28 106
28 184
31 191
34 105
39 103
41 101
41 210
42 212
43 214
44 99
45 215
47 96
48 216
49 93
51 215
54 87
54 213
56 84
56 210
60 78
65 191
66 43
68 184
69 47
71 49
73 52
73 54
77 56
82 60
85 62
87 63
89 64
92 65
98 66
104 65
107 64
109 63
112 62
114 60
119 56
125 49
127 47
130 43
When plotted will give 3 different curves. But while finding the max returns only the peak of the highest curve.
Upvotes: 1
Views: 454
Reputation: 35109
Here's a quick and dirty solution which is definitely not general, definitely slow, and probably saves only a little bit of manual work. It goes along your x
vector and tries to sort your points into equivalence classes, based on the distance of consecutive points. This might be a bit more general than the solution of anon0909, but could still fail for less well-separated data, and needs manual tweaking for a proper choice of radius.
Code:
%sort to be on the safe side
[x inds]=sort(x);
y=y(inds);
eqradius=15; %the key parameter
equivs=[];
equivs(1).ind=1;
equivs(1).x=x(1); %redundant but useful
equivs(1).y=y(1); %redundant but useful
for i=2:length(x) % go over remaining points
foundone=0;
for eqclass=1:length(equivs) %go over found equivalence classes
if norm([x(i) y(i)] - [equivs(eqclass).x(end) equivs(eqclass).y(end)])<eqradius
foundone=1;
equivs(eqclass).ind = [equivs(eqclass).ind; i];
equivs(eqclass).x = [equivs(eqclass).x; x(i)];
equivs(eqclass).y = [equivs(eqclass).y; y(i)];
end
if foundone==1
break %break eqclass if
end
end
if ~foundone
equivs(length(equivs)+1).ind = i;
equivs(length(equivs)).x = x(i);
equivs(length(equivs)).y = y(i);
%else
% continue % but the loop is already over
end
end
%plot classes
figure;
eqclass=1;
hold all;
legendcell={};
for eqclass=1:length(equivs)
plot(equivs(eqclass).x,equivs(eqclass).y,'o');
legendcell{end+1}=num2str(eqclass);
end
legend(legendcell);
As you can see, in your case for eqradius=15
we unintentionally separate curve number 2 into 3 separate equivalence classes, so you'd still need some manual labour. Or you could try increasing eqradius
, but this will eventually lead to your curves smearing into each other.
Probably the only case when this is a better solution than the one referenced, is when you have two curves in the same y
band but separated well in x
...
Upvotes: 1
Reputation: 11171
These questions depend sensitively on features in your data set that you can/cannot assume, as well as to what extent you'd like to automate in code. However, from the data you provided, it looks like you can simply separate each bump by their y values, and take each maximum of the subset. I.e., something like this:
y1 = y(y<=75);
y2 = y(75<y<=150);
y3 = y(y>150);
max1 = max(y1);
max2 = max(y2);
max3 = max(y3);
Upvotes: 0