fitting peak points maxima
4 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Ancalagon8
am 22 Mai 2020
Bearbeitet: Ancalagon8
am 6 Jan. 2025
I am facing some problems trying to create a curve that will pass through maximum peaks. Will a solution be to export peaks into a new array, plot them and then create a fitting curve or there is another way?
Thanks in advance!
0 Kommentare
Akzeptierte Antwort
Image Analyst
am 22 Mai 2020
Just try interp1() or spline(). Pass in your peak points and then the x values of the whole array, something like
[peakValues, indexes] = findpeaks(Sig);
yOut = spline(indexes, peakValues, 1:length(Sig));
plot(yOut, 'b-', 'LineWidth', 2);
grid on;
Let me know if it works. Attach your Sig data if it doesn't. Accept this answer if it does.
6 Kommentare
Image Analyst
am 25 Mai 2020
Bearbeitet: Image Analyst
am 25 Mai 2020
We need to make the table from ONLY the peak points, not all of them, so
% Define coefficients and function that the X values obey.
tbl = table(x(peakIndexes)', y(peakIndexes)');
NOT
% Define coefficients and function that the X values obey.
tbl = table(x(:), y(:));
New code:
clc; % Clear the command window.
fprintf('Beginning to run %s.m.\n', mfilename);
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
s = load('sig.mat')
y = s.Sig3b;
% Get rid of negative.
y(y<0) = [];
x = 1 : length(y);
plot(x, y, 'b', 'MarkerSize', 15);
grid on
[peakValues, peakIndexes] = findpeaks(y, 'MinPeakDistance', 15);
hold on;
plot(peakIndexes, peakValues, 'r.', 'MarkerSize', 30);
% Interpolate
yFit = spline(peakIndexes, peakValues, x);
plot(x, yFit, 'r-');
% Define coefficients and function that the X values obey.
tbl = table(x(peakIndexes)', y(peakIndexes)');
% Define the model as Y = a * exp(-b*x) + c
% Note how this "x" of modelfun is related to big X and big Y.
% x((:, 1) is actually X and x(:, 2) is actually Y - the first and second columns of the table.
modelfun = @(b,x) b(1) * exp(-b(2)*x(:, 1)) + b(3);
% Guess values to start with. Just make your best guess.
aGuessed = 6000 % Arbitrary sample values I picked.
bGuessed = 0.004
cGuessed = 0
beta0 = [aGuessed, bGuessed, cGuessed]; % Guess values to start with. Just make your best guess.
% Now the next line is where the actual model computation is done.
mdl = fitnlm(tbl, modelfun, beta0);
coefficients = mdl.Coefficients{:, 'Estimate'}
% Create smoothed/regressed data using the model:
yFitted = coefficients(1) * exp(-coefficients(2)*x) + coefficients(3);
% Now we're done and we can plot the smooth model as a red line going through the noisy blue markers.
hold on;
plot(x, yFitted, 'r-', 'LineWidth', 2);
grid on;
title('Exponential Regression with fitnlm()', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
legendHandle = legend('Noisy Y', 'Fitted Y', 'Location', 'north');
legendHandle.FontSize = 30;
% Place formula text roughly in the middle of the plot.
formulaString = sprintf('Y = %.3f * exp(-%.3f * X) + %.3f', coefficients(1), coefficients(2), coefficients(3))
xl = xlim;
yl = ylim;
xt = xl(1) + abs(xl(2)-xl(1)) * 0.325;
yt = yl(1) + abs(yl(2)-yl(1)) * 0.59;
text(xt, yt, formulaString, 'FontSize', 25, 'FontWeight', 'bold');
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')

Note that there are some peaks early on below 3000, so you'll need to experiment around with findpeaks() if you want to eliminate those and get a better fit.
Note: If you want to specify a point for the y axis intercept, that is possible by adjusting the model. As it is, it tries to give its best guess.
Image Analyst
am 18 Jun. 2020
Yes. Did you try to change the model? It's not hard. See attached.

Weitere Antworten (0)
Siehe auch
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!