# Find peaks/valleys of a noisy signal

161 views (last 30 days)

Show older comments

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

Walter Roberson
on 18 Dec 2020

### Accepted Answer

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);

### More Answers (1)

Image Analyst
on 18 Dec 2020

### See Also

### Community Treasure Hunt

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

Start Hunting!