How to fit a sine curve with only the maximum and minimum values
14 次查看(过去 30 天)
显示 更早的评论
Hi, I am trying to plot a sine wave through the high and low water points from a measuring station in the North Sea.
The image shows the first few data points. I've tried fitting a curve, filling the gaps etc. but I can't get Matlab to acknowledge the oscillating signal.
Help will be appreciated, thank you!
this is the goal:
2 个评论
Sam Chak
2024-4-8
It might be easier to fit a custom sinusoidal waveform if the data is converted to the unit of 'seconds'. However, it is important to note that the time step in the t vector is not uniform.
where and are the time-varying amplitude and the time-varying period of the sine wave, respectively.
T = readtable("datapoints.xlsx", VariableNamingRule="preserve")
x = T{:,1}; % datetime data
t = seconds(x - x(1)); % convert to seconds
A = T{:,2}; % high and low points of the sea level
stem(t, A), grid on, xlabel('Time (sec)'), ylabel('Sea level')
title('Sea level around the North Sea from 1st to 15th, Jan 2022')
回答(2 个)
Bruno Luong
2024-4-8
编辑:Bruno Luong
2024-4-8
piecewise (co)sine interpolation (not fitting).
I don't think you have extra DOF to play with if you restrict data to be local extrema and model follows a sinusoidal law.
data = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1662781/datapoints.xlsx');
t=datenum(data.t_datetime);
dt = t-t(1);
y = data.t_datenum;
dti = linspace(min(dt),max(dt),1025);
yi = sininterp(dt, y, dti); % function defined below
% Ploy check result
figure
subplot(2,1,1)
dtfun = @(dt) datetime(dt+t(1),'ConvertFrom','datenum');
h = plot(dtfun(dt),y,"ob",dtfun(dti),yi,"r");
% zoom plot
ax2 = subplot(2,1,2);
h = plot(dtfun(dt),y,"ob",dtfun(dti),yi,"r");
xlim(ax2, dtfun([8 11]))
%%
function yi = sininterp(t, y, ti)
ti = ti(:);
i = discretize(ti, t);
yi = nan(size(ti));
valid = i>=1 & i<numel(ti);
i = i(valid);
y1 = y(i);
y2 = y(i+1);
ym = (y1+y2)/2;
A = (y1-y2)/2;
alpha = (ti(valid) - t(i)) .* (pi./(t(i+1)-t(i)));
yi(valid) = ym + A.*cos(alpha);
end
R
2024-4-8
Hi Particia,
Fitting a piecewise cubic Hermite ("pchip") curve might help with this use case. Here is an example of the same
% Read data from Excel file
data = readtable('datapoints.xlsx');
% Convert first column to string array for time labels
time = string(table2array(data(:, 1)));
% Extract water level data from second column
waterLevel = table2array(data(:, 2));
% Create index array for plotting
x=(1:58)'; % Ensure x is a column vector
% Plot water level data
plot(x,waterLevel,".");
title('Water Level vs. Time');
xticklabels(time) % Set custom x-axis tick labels
% Fit a piecewise cubic Hermite interpolating polynomial
[curve,gof,output] = fit(x,waterLevel,"pchipinterp");
% Overlay fitted curve on the plot
hold on
plot(curve)
hold off
Here is the plot I get after executing the above code:
Refer to the following link to learn more about 'pchipinterp' curve fitting model:
You can also find a list of curve fitting models that MATLAB supports in the following documentation:
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Linear and Nonlinear Regression 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!