Find specific peaks and their positions

28 次查看(过去 30 天)
Good afternoon,
I have an ongoing problem where I want to find the specific peaks and localities within a data set automatically. The test data shows 4 typical data plots that can be found in a simulation that I am running. What I need jpeg shows 9 locations in total, the problem I have is that I cannot capture these points across all the data sets because the peak count is different owing to different areas of the simulation they were taken.
My method has been to find the peak locations, plot these as these changes (2nd figure) represent the change in water level, then find the gradient and where these changes occur from positve to negative. However, this has not worked because some of the trends continue to be negative. So, I tried interpolating, "ischange" with variance, mean etc and including filtering, smoothing, islocal max, findpeakpts and I still cannot capture what I need.
Is there a way to do this?
  2 个评论
Star Strider
Star Strider 2019-12-27
The signals in ‘test_data.mat’ are sinusiods. They do not look anything like the plot you posted.
We need to see the code — and data — you used to get those plots.
Richard Rees
Richard Rees 2019-12-27
Hi, I thought I put the code on before I went out. Below is just the base code that I have been working with, the graphs generated are to see if things are working as expected. Then I would track back and identify the positions in A.
close;clc;clear
load 'test_data.mat'
A = Test_data;
%Show data samples
figure(1)
for i = 1:size(A,1)
plot(A(i,:));
hold on
end
legend
xlabel('Timestep')
ylabel('PWP (kPa)')
%% Use find peaks to find locations
figure(2)
for i = 1:size(A,1) % best to try at i = 1 first
[ppks{i},plocs{i}] = findpeaks(A(i,:));
[nppks{i},nlocs{i}] = findpeaks(-A(i,:));
x = 1:length(ppks{i}); % X is not consistant
%mov_ppks{i} = movmean(ppks{i},3); % Smooth data, use as grad variable
gppks{i} = gradient(ppks{i}); %gradient
%is_gppks{i} = ischange(gppks{i}, 'variance', 'Threshold',5); %Tried linear and mean at differing gradient thresholds
si_gppks{i} = sign(gppks{i}); %Change of sign for gradient
is_gppks{i} = ischange(si_gppks{i}); % Find changes
yyaxis left
ylabel ('PWP (kPa)')
xlabel ('Peak number from ppks')
plot(ppks{i},'k') %Plot peaks
hold on
plot(x(is_gppks{i}),ppks{i}(is_gppks{i}),'r*');
hold on
yyaxis right
ylabel('Gradient')
plot(gppks{i},'b') %Gradiant of ppks
hold on
end

请先登录,再进行评论。

采纳的回答

Cris LaPierre
Cris LaPierre 2019-12-28
编辑:Cris LaPierre 2019-12-28
This is quick and dirty, but it finds 8 of the 9 peaks you specified (technically #9 is not a peak, so I leave it to you to determine how to handle it).
Basically, I compute the abs difference of the signal you indicated. This creates peaks at each step change. I can then use findpeaks to identify the location of these peaks. I used the MinPeakProminence name-value pair to help select just the desired peaks.
Here's the code (first 2 lines) plus a visualization to check the results.
stpData = abs(diff(ppks{4}));
[pks,loc]=findpeaks(stpData,"MinPeakProminence",0.25);
figure
plot(ppks{4})
hold on
plot(stpData)
plot(loc,ppks{4}(loc),'ro')
peaks_richardRees.png
  1 个评论
Richard Rees
Richard Rees 2019-12-31
Thanks for the reply, I adapted the code and it works now. Thanks very much.

请先登录,再进行评论。

更多回答(0 个)

标签

产品


版本

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by