Making something like 'findpeaks' function without using threshold
이전 댓글 표시
Hi! i want to ask about the code i am making. i am making myself a for loop like a finpeaks (but i don't want to use that and any threshold for a more automatic approach) on my data and i am having a problem with showing the valid peaks/valleys because some ot the shown peaks/valleys were not the one i want to be shown. I have my code here and was cracking my brains out for a solution. If you look at the photo, the plot cannot show some valid peaks/valleys (colored greed), and some non valid ones are shown in some. Can you help me?
I attached the data and the photo of the plot.
% Design for bandpass filter (Butterworth filter)
fs = 1000; % Sampling frequency
f_low = 0.1; % Low cutoff frequency
f_high = 10; % High cutoff frequency
order = 2; % Filter order
% Bandpass filtering
[b, a] = butter(order, [f_low, f_high]/(fs/2));
mag_filtered = filtfilt(b, a, acc);
% Set up plot with aspect ratio adjustment
figure;
% Plot for the main data
h_main = plot(NaN, NaN, 'k'); % Main plot in black
hold on;
h_peaks = plot(NaN, NaN, 'or'); % Red markers for peaks
h_valleys = plot(NaN, NaN, 'ob'); % Blue markers for valleys
xlabel('Time (s)');
ylabel('Filtered Magnitude');
title('Animated Peaks and Valleys');
% Set up additional plot for the entire data
h_total = plot(NaN, NaN);
% Set up additional plot for the animated entire data
h_total_animated = plot(NaN, NaN, 'k');
% Set up a new figure for temporary data
figure;
h_temp = plot(NaN, NaN);
xlabel('Time (s)');
ylabel('Filtered Magnitude');
title('Temporary Data');
% Animation parameters
step = 300; % Number of points/data to display in each step
delay = 0.01; % Delay between steps in seconds
% Initialize arrays to store peaks and valleys
peaks_x = [];
peaks_y = [];
valleys_x = [];
valleys_y = [];
% Initialize additional variables
time_total = [];
mag_total = [];
time_data_new = [];
mag_data_new = [];
% Initialize variables to track highest peak and lowest valley
highest_peak = -inf;
lowest_valley = inf;
% Initialize variables to track all peaks and valleys
all_peaks_x = [];
all_peaks_y = [];
all_valleys_x = [];
all_valleys_y = [];
% Initialize variables to track the number of steps since the last peak or valley
steps_since_peak = 0;
steps_since_valley = 0;
% Main loop for animation
for i = 1:step:numel(time)
% Extract a portion of data for the current step
time_data_new = time(i:min(i+step-1, numel(time)));
mag_data_new = mag_filtered(i:min(i+step-1, numel(time)));
% Find the highest peak and lowest valley within the current step
max_value = max(mag_data_new);
min_value = min(mag_data_new);
% Update the highest peak and lowest valley if found
if max_value > highest_peak
highest_peak = max_value;
peaks_x = time_data_new(mag_data_new == highest_peak);
peaks_y = highest_peak;
steps_since_peak = 0;
else
steps_since_peak = steps_since_peak + 1;
end
if min_value < lowest_valley
lowest_valley = min_value;
valleys_x = time_data_new(mag_data_new == lowest_valley);
valleys_y = lowest_valley;
steps_since_valley = 0;
else
steps_since_valley = steps_since_valley + 1;
end
% Update all peaks and valleys arrays
all_peaks_x = [all_peaks_x peaks_x];
all_peaks_y = [all_peaks_y peaks_y];
all_valleys_x = [all_valleys_x valleys_x];
all_valleys_y = [all_valleys_y valleys_y];
% Update plot for the entire data
set(h_total, 'XData', time(1:i), 'YData', mag_filtered(1:i));
% Update plot for animated entire data
set(h_total_animated, 'XData', time(1:i), 'YData', mag_filtered(1:i));
% Update main plot
set(h_main, 'XData', time_data_new, 'YData', mag_data_new);
% Update plot
drawnow; % Force the plot to refresh
pause(delay);
% Plot all stored peaks and valleys
set(h_peaks, 'XData', all_peaks_x, 'YData', all_peaks_y);
set(h_valleys, 'XData', all_valleys_x, 'YData', all_valleys_y);
% Update plot for time_temp and mag_temp
set(h_temp, 'XData', time_data_new(:), 'YData', mag_data_new(:));
drawnow;
pause(delay);
% Reset the highest peak and lowest valley if no new peak or valley is found within 10 steps
if steps_since_peak >= 10
highest_peak = -inf;
end
if steps_since_valley >= 10
lowest_valley = inf;
end
end
댓글 수: 2
Steven Lord
2024년 3월 14일
If one of the reasons you don't want to use findpeaks is because you don't have Signal Processing Toolbox, take a look at the islocalmax and islocalmin functions in MATLAB.
Stella
2024년 3월 15일
채택된 답변
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Descriptive Statistics에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

