Azzera filtri
Azzera filtri

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

4 visualizzazioni (ultimi 30 giorni)
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?

Risposta accettata

Matt J
Matt J il 31 Gen 2024
Modificato: Matt J il 31 Gen 2024
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 Commenti
Matt J
Matt J il 31 Gen 2024
Modificato: Matt J il 31 Gen 2024
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 il 31 Gen 2024
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!

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

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

Start Hunting!

Translated by