필터 지우기
필터 지우기

How do I make the fit better so that there are no negative y-values for the fit?

조회 수: 4 (최근 30일)
I am attempting to fit a cubic spline to rheological data which can be found in the attached excel file. The data is best visualized on a log-log plot, however, the cubic spline being fit between some points has negative y-values. How do I improve the fit between these points? The code is below:
clc;
clear all;
%% --Variable Assignment--
osc_strain = xlsread("ag_gel_data.xlsx",1,'A1:A25');
stor_mod = xlsread("ag_gel_data.xlsx",1,'K1:K25');
loss_mod = xlsread("ag_gel_data.xlsx",1,'L1:L25');
osc_strain_t = xlsread("ag_gel_data.xlsx",1,'A1:A21');
stor_mod_t = xlsread("ag_gel_data.xlsx",1,'K1:K21');
tb1 = table(osc_strain,stor_mod,loss_mod);
%% --Fit: Cubic Spline Interpolant--
[xData, yData] = prepareCurveData( osc_strain, stor_mod );
% Set up fittype and options.
ft = 'cubicinterp';
excludedPoints = yData < 0;
opts = fitoptions( 'Method', 'CubicSplineInterpolant' );
opts.ExtrapolationMethod = 'none';
opts.Exclude = excludedPoints;
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
%% --Plotting--
lg1 = loglog(tb1,"osc_strain","stor_mod",'LineWidth',1);
hold on;
lg2 = loglog(tb1,"osc_strain","loss_mod",'LineWidth',1);
% Plot fit with data on a log-log scale.
h = plot(fitresult);
%% --Figure Stylization--
lg1.LineStyle = "-";
lg1.Color = "magenta";
lg1.Marker = ".";
lg1.MarkerSize = 16;
lg2.LineStyle = "-";
lg2.Color = "magenta";
lg2.Marker = "o";
lg2.MarkerSize = 4;
h.LineStyle = "--";
h.Color = "black";
xlabel('Oscillation Stress, \gamma (%)')
ylabel("G',G'' (Pa)")
legend('Storage Modulus','Loss Modulus','Cubic Spline','Location','northwest')
Below is the figure that is produced. The splines between the last 6 data points are the ones I would like to smooth more. Any ideas?

채택된 답변

Matt J
Matt J 2024년 1월 31일
편집: Matt J 2024년 1월 31일
Why use fit() if you just want to interpolate? Why not use interp1 with the 'pchip' method instead?
clc;
clear all;
%% --Variable Assignment--
osc_strain = xlsread("ag_gel_data.xlsx",1,'A1:A25');
stor_mod = xlsread("ag_gel_data.xlsx",1,'K1:K25');
loss_mod = xlsread("ag_gel_data.xlsx",1,'L1:L25');
osc_strain_t = xlsread("ag_gel_data.xlsx",1,'A1:A21');
stor_mod_t = xlsread("ag_gel_data.xlsx",1,'K1:K21');
tb1 = table(osc_strain,stor_mod,loss_mod);
%% --Fit: Cubic Spline Interpolant--
[xData, yData] = prepareCurveData( osc_strain, stor_mod );
%% --Plotting--
lg1 = loglog(tb1,"osc_strain","stor_mod",'LineWidth',1);
hold on;
lg2 = loglog(tb1,"osc_strain","loss_mod",'LineWidth',1);
% Plot fit with data on a log-log scale.
xup=linspace(xData(1) , xData(end),1e4);
h = plot(xup, interp1(xData,yData,xup,'pchip'),'--');
%% --Figure Stylization--
lg1.LineStyle = "-";
lg1.Color = "magenta";
lg1.Marker = ".";
lg1.MarkerSize = 16;
lg2.LineStyle = "-";
lg2.Color = "magenta";
lg2.Marker = "o";
lg2.MarkerSize = 4;
h.LineStyle = "--";
h.Color = "black";
xlabel('Oscillation Stress, \gamma (%)')
ylabel("G',G'' (Pa)")
legend('Storage Modulus','Loss Modulus','Cubic Spline','Location','northwest')
  댓글 수: 12
Matt J
Matt J 2024년 1월 31일
편집: Matt J 2024년 1월 31일
Perhaps as follows?
K = gradient(yup,xup);
Ktable0 = [xup; K].';
Ktable1=Ktable0(K>=0,:);
You realize I hope that the region where the gradient is >=0 may not be contiguous. Basically, you are keeping only the regions where stor_mod is increasing and discarding wherever it is decreasing.
Elias Kerstein
Elias Kerstein 2024년 1월 31일
Thank you so much! Your solution worked. Yes, I am aware, however the culture surrounding how rheological data is plotted demands it to be on a log-log plot, which eliminates the region in which yData decreases. I greatly appreciate your assistance!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Interpolation에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by