finding prominent maxima and minima of a column vector

Hello,
Suppose I Have a column vector wcich has multiple maxima and minima, I just want to find the index of N= 4 number of them ( prominent maxia and minima).
And if I use something like 'findpeak' then it gives a lots of local max and min as for a noisy signal. I want to get the prominant max & min indices of the 2nd colm of the attachment please.
Thank you

 Risposta accettata

Although findpeaks needs some help here, it can find all four:
[D,S] = xlsread('ab1.xlsx');
[pks,plocs] = findpeaks([D(:,2); min(D(:,2))], 'MinPeakProminence',1); % Append ‘0’ To Far End To Identify Last Peak
[vls,vlocs] = findpeaks(-D(:,2), 'MinPeakProminence',1)
figure
plot(D(:,1), D(:,2))
hold on
plot(D(plocs,1), pks, '^r')
plot(D(vlocs,1), vls, 'vr')
hold off
grid
legend('Data','Peaks','Valleys')
The associated times are: D(plocs,1).
pks =
1.2000
1.2001
1.2001
1.2000
locs =
3165
4072
4675
5138
Similarly for the valleys:
vls =
1.0e-04 *
-0.0140
0.3678
0.5941
-0.1694
vlocs =
2708
3753
4446
4954

2 Commenti

Thank you so much Mr. strider.
I have little question,
why we need S here?
on the 2nd line why this is nessary at the last portion min(D(:,2))],
Thank you
As always, my pleasure.
We need ‘S’ so I know what the columns represent. (More knowledge is generally better.) There is no absolute guarantee that the first column is time. You mentioned a column vector, not the second column of an (Nx2) matrix, so I had to be sure I knew what I was working with.
The findpeaks function does not consider the end of a vector to be a peak, so it will never return that as a peak. Concatenating that vector with the minimum of the vector creates a peak (as far as findpeaks knows) where one did not previously exist. Since you stated that there were four peaks, and the last one looked like the first three (as much as we can see of it, anyway), I made it a peak by defining a lower value after it. (I do not generally recommend creating data where none previously existed, however here it seemes safe in order to define the last peak.)

Accedi per commentare.

Più risposte (1)

az
az il 21 Giu 2019
Thank you Mr. Strider for your explanation.
The reason I was trying to finf the peaks and vallys is that I want break the whole data to several segment from one peak to velly, vally to peak.
Here is mt whole data file where the column 8th was time and 12 was voltage I separately gave you before. and Column 25 has capacity that is sorted to start from origin in time axes everytime for a segment of data, from peak to vally , vally to peak.
I am using your code in capacity3.m file before segmenting data.
I think line 17 in not necessary as your code already gived 'plocs' 'vlocs' ascending order. I just want to be sure about the order.
But for chopping the data I am using the clumsy codes from line 19th to 26th, and this actually does not chopping the data as the data point remain connected. So is there any short cut way that I can chop the data after a peak or vally and start from next data point without loasing the data.
Thanks.

9 Commenti

Try this:
idxv = sort([plocs; vlocs]); % Concatenate Peak & Valley Vectors & Sort Ascending
for k = 1:numel(idxv)-1
Segments{k} = D(idxv(k):idxv(k+1),2); % Store Data Between Indices
end
That should do what you want. Note that it begins from the first valley, and stores to the next peak, then stores to the next valley ... until it finished. Here, there are 7 segments total.
Than you Mr. Strider, It seems to work. But instead on saving only saving only the dependent variable values, can I save it with indipendent variable values like, 7 of the (segment rows *2) double. So that I could plot easily.
Thank you.
As always, my pleasure.
To do that, simply change the ‘Segments’ assignment to:
Segments{k} = D(idxv(k):idxv(k+1),:);
That captures both columns.
Thank you Mr. Strider, for answering all my questions so patiently.
Your cods works fine.
I just able to get all the sigments {1*8} cell by just starting from 1
idxv = [1;sort([plocs; vlocs])];
Now for ploting from cell while I am using,
figure;
hold on;
for i = 1:length(Segments)
plot(Segments{i}) ;
end
hold off
markers = {'b', 'g', 'o', 'r', 'm', 'y', 'k', 'kh'};
I am geting graph looks okay but the x axis values are wrong. It seems to taking the index value as x axes value. the x axes range is from 0: 0.2930, that is from index (1:1st minima that is at index nember 2708.).
Y axex value is okay.
So is there any other command to plot from cell so that it will take the real axes value not index value.
Thanks
The index values shouldn’t enter into it.
This works for me, and the data have the same x-values as the original data (I checkled):
figure
hold all
for k = 1:numel(Segments)
plot(Segments{k}(:,1), Segments{k}(:,2))
end
hold off
grid
Compare with:
figure
plot(D(:,1), D(:,2))
They are the same.
Thank you Mr. Strider.
There is one last question I have, that is when I use this code
idxv = sort([plocs; vlocs]);
for k = 1:numel(idxv)-1
Segments{k} = D(idxv(k):idxv(k+1),2);
end
is there any I can save the individual data segments as a 'double' or 'table' instead of 'cell'. I tried many ways to convert cell to double but did not work.
If they are individual double data then I can plot separately and merge at last.
Now if I use this code
for k = 1:numel(Segments)
plot(Segments{k}(:,1), Segments{k}(:,2))
end
then I got the 'capture1' image. which is not segmented graph at all because it joint the data value between each segment.
but If I use
plot(Segments{i}) ;
then I got the 'capture' image which is segmented data points (does not get connected between each segments) but the reason is it takes indexnumber as the x axis which is ever increasing.
It seems the only solution is to save the data segments as a table or double.
Thank you.
is there any I can save the individual data segments as a 'double' or 'table' instead of 'cell'
You can convert them to individual double matrices, or to tables if you like. The problem is that they contain different numbers of elements, so you can’t concatenate them into a 3D array, for example. You could use the cell2mat function to save each ‘Segments’ cell as a separate matrix, however this makes for very inefficient code when you go to use them later.
With respect to the plots, I am still not certain what you want.
Try these:
figure
hold all
for k = 1:numel(Segments)
plot(Segments{k}(:,1)-Segments{k}(1,1), Segments{k}(:,2))
end
hold off
The first loop plots the individual segments.
figure
hold all
for k = 1:2:numel(Segments)-1
plot(Segments{k}(:,1)-Segments{k}(1,1), Segments{k}(:,2))
plot(Segments{k+1}(:,1)-Segments{k}(1,1), Segments{k+1}(:,2))
end
plot(Segments{end}(:,1)-Segments{end}(1,1), Segments{end}(:,2))
hold off
The second loop plots them as complete waveforms, with the respective ascending and descending segments linked.
Both of these should also give you a good idea of how to address the ‘Segments’ cells.
Thank you Mr. Strider for helping me all the way.
This 'capture2' is the graph that actually I wanted.
I realize there are mostly 5 cionnecting data points after a vally to starting points of the curve leads toward peak.
And Almost 4 connecting data points after a peak to the starting curve leads towards vally.
So in capacity3.m I omit those data points manually from line 19th to 26.
Is there any way two for loop ( one for index_min or index_max row number , another for number to add (5/4) to even/odd number of index (index2/ index3 ) can do that?
Thank you
As always, my pleasure.
So in capacity3.m I omit those data points manually from line 19th to 26.’
There are several way to do this, one is to completely eliminate them by setting that range equal to the empty array [], another is to set them equal to NaN. What you do depends on the result you want.
I ran your code, and it seems to do what you want. There are several connecting lines that appear strange to me (they do not appear on the plots my code produces), however looking at your plot calls, you added them specifically, so they are not artefacts.
I do not understand what you want to do, especially with respect to adding more for loops. I encourage you to experiment to get your code to do what you want it to.

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by