Find peaks/valleys of a noisy signal

I have this signal which is noisy as well as it has too much data samples. When I try to find the peaks or valleys, it gives multiple peaks/valleys around the same point probably because the data is noisy and has too many samples. I did use the 'MinPeakDistance' and also tried using the 'MinPeakHeight' and also the 'Threshold' but all time I get many peaks's around a given time instant. In other words, I would want only one peak at the peak of the signal and one valley at the trough of the signal. I have the data attached to the post too. Thanks in advance.
It is just a two column data and I plot the 2nd column wrt 1st one. I would prefer to measure valleys and I would actually need both.
[pks locs] = findpeaks(data_compact(:,2),'MinPeakHeight',0.992*max(data_compact(:,2)),'MinPeakDistance',5000e-3); % peaks
data_inverted(:,1) = data_compact(:,1);
data_inverted(:,2) = -data_compact(:,2);
%[valley valleys_locs] = findpeaks(data_inverted(:,2),'MinPeakDistance',0.2e-3); % valleys

7 Comments

I think the .mat file does not match the figure.
I think he just included a small subset of the data.
s = load('data_compact.mat')
data_compact = s.data_modified;
% Smooth with a savitzky-golay filter
% data_compact(:, 2) = sgolayfilt(data_compact(:, 2), 2, 151);
plot(data_compact(:,1), data_compact(:,2), 'b-');
grid on;
[pks, locs] = findpeaks(data_compact(:,2),'MinPeakHeight',0.992*max(data_compact(:,2)),'MinPeakDistance',5000e-3); % peaks
hold on;
plot(data_compact(locs, 1), pks, 'r.', 'MarkerSize', 10);
% Find Valleys
data_inverted(:,1) = data_compact(:,1);
data_inverted(:,2) = -data_compact(:,2);
% [valleyValues valleysIndexes] = findpeaks(data_inverted(:,2),'MinPeakDistance',0.2e-3); % valleys
% plot(data_inverted(valleysIndexes, 1), -valleyValues, 'r.', 'MarkerSize', 10);
Yes, so this has many peaks (red) on a single peak of the signal as you can see in the image. This might be because of the noise, but I would like only one peak and hence, I want to count the total number of peaks in this signal which is my end goal.
Hello Image Analyst, could you please remove the data if possible?
The data is part of the question; the question does not make sense without the data.
Jay Vaidya
Jay Vaidya on 18 Dec 2020
Edited: Jay Vaidya on 18 Dec 2020
Yes, but I would like to put another data instead of this data, as this is not that important to what I am intending to do. I also cannot delete the question. I currently don't need to solve this problem and the data can be misused.
No-one knows what your data means, or who or what it was created from. It is therefore difficult to "misuse".

Sign in to comment.

 Accepted Answer

Image Analyst
Image Analyst on 18 Dec 2020
Edited: Image Analyst on 19 Dec 2020
Try this:
clc; % Clear the command window.
clear all;
close all;
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 22;
fprintf('Beginning to run %s.m ...\n', mfilename);
%--------------------------------------------------------------------------------------------------
% Load data from mat file.
s = load('data_compact.mat')
data_compact = s.data;
x = data_compact(:,1);
% Plot data.
plot(x, data_compact(:,2), 'b-');
xlim([x(1), x(end)]);
grid on;
hold on;
%--------------------------------------------------------------------------------------------------
% Smooth with a savitzky-golay filter. Polynomial order = 2, window width = 351 elements.
smoothY = sgolayfilt(data_compact(:, 2), 2, 351);
plot(x, smoothY, 'r-');
%--------------------------------------------------------------------------------------------------
% Find peaks. Must be separated by 13000 elements.
[peakValues, indexesOfPeaks, widths, proms] = findpeaks(smoothY, 'MinPeakDistance',13000); % peaks
% Remove an occasional outlier that is below the midpoint.
meanSignal = mean(smoothY);
outlierIndexes = peakValues < meanSignal;
peakValues(outlierIndexes) = [];
indexesOfPeaks(outlierIndexes) = [];
% Plot peaks.
plot(x(indexesOfPeaks), peakValues, 'g.', 'MarkerSize', 30);
%--------------------------------------------------------------------------------------------------
% Find Valleys. Must be separated by 13000 elements.
[valleyValues, indexesOfValleys] = findpeaks(-smoothY, 'MinPeakDistance', 13000); % valleys
valleyValues = -valleyValues; % Make upright again.
% Remove an occasional outlier that is above the midpoint.
outlierIndexes = valleyValues > meanSignal;
valleyValues(outlierIndexes) = [];
indexesOfValleys(outlierIndexes) = [];
% Plot valleys.
plot(x(indexesOfValleys), valleyValues, 'c.', 'MarkerSize', 30);
message = sprintf('Found %d peaks, and %d valleys', length(indexesOfPeaks), length(indexesOfValleys));
title(message, 'FontSize', fontSize);
% Maximize the figure window.
g = gcf;
g.WindowState = 'maximized'
fprintf('%s\n', message);
uiwait(helpdlg(message));
fprintf('Done running %s.m ...\n', mfilename);

6 Comments

Hey thanks, it works. It would be great if you can remove the data files from both your messages because the problem is solved.
The data is part of the question, and the question loses meaning without the data. https://www.mathworks.com/matlabcentral/answers/696995-find-peaks-valleys-of-a-noisy-signal#comment_1215630
I understand, but can you then only keep the data set (column 1 and 2) instead of the all columns? Rest of the columns are not a part of the question. I hope this is fine at least.
Image Analyst
Image Analyst on 19 Dec 2020
Edited: Image Analyst on 19 Dec 2020
OK, post it for me and I'll replace it. However, like Walter said, no one has any idea what this data represents, much less the other columns, so I don't think you need to worry about leaking any proprietary/secret information. And I do think it's a nice example of how to filter noisy data to find peaks in the presence of noise.
Ok, thanks. Here it is. Please replace this file in both the posts with your older attachments.

Sign in to comment.

More Answers (1)

If there is noise on your peaks, have you tried sgolayfilt() with order 2 or 3? It's in the Signal Processing Toolbox.

Products

Release

R2020b

Community Treasure Hunt

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

Start Hunting!