How can I better control bestfit lines

1 view (last 30 days)
I have a piece of code that generates a best fit line alongside error bars. As well as a best fit for a scatter graph.
I am trying to be able to adjust the best fit line.
The data is in tabular for as follows
Strength_MPa = [
20 2880
20 3280
20 3990
1200 2000
1200 2990
1200 3500
1300 2200
1300 2700
1300 3280
1400 1390
1400 1770
1400 2150 ];
Grainsize_nm = [
25 90
1200 120
1300 150
1350 310
1400 450
1500 790 ];
% Nextel 610
figure1 = figure;
%
y = reshape(Strength_MPa,3,[]);
%
x = y(1,1:end/2);
%
%
y_min = y(1,end/2+1:end);
%
y_mid = y(2,end/2+1:end);
%
y_max = y(3,end/2+1:end);
%
%% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( x, y_mid );
%
%
% Set up fittype and options.
ft = fittype( 'power2' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [2450.16071129496 -0.0464507882616668 0.160697077002396];
%
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
%
% Plot fit with data.
% figure( 'Name', 'untitled fit 1' );
h = plot(fitresult, xData, yData);
% h.Color = 'b';
% h.LineStyle = '-';
% h.Marker = 'none';
% legend( h, 'y_mid vs. x', 'untitled fit 1', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y_mid', 'Interpreter', 'none' );
grid off
%
hold on
%%
yyaxis left
%
errorbar(x,y_mid,y_mid-y_min,y_max-y_mid,'LineStyle','none')
%
ylim([0 4500])
%
ylabel('Strength [MPa]','Color',[ 0 0 0 ])
%
ax = gca;
%
ax.YColor = 'k';
%
%
yyaxis right
%
x = (Grainsize_nm(:,1));
y = (Grainsize_nm(:,2));
%% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( x, y );
% Set up fittype and options.
ft = fittype( 'exp1' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [58.0338200304954 0.00142172529592695];
% opts.StartPoint = [25 90];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
%
% Plot fit with data.
h = plot( fitresult, xData, yData );
% legend( h, 'y vs. x', 'untitled fit 1', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y', 'Interpreter', 'none' );
% grid off
plot(Grainsize_nm(:,1),Grainsize_nm(:,2),'-ro','MarkerFaceColor','r','LineStyle','none')
%
ylim([0 900])
%
ylabel('Grainsize [nm]','Color',[ 0 0 0 ])
%
xlim([0 1600])
%
ax = gca;
%
ax.YColor = 'k';
%
%
There are some issues I have with the code.
Firstly I confess I have used the curve fittter app as I am quite a rookie on MatLab, I have also leaned heavily on the community to get the plots lookig as they are so far, which is greatly appreciated.
Despite me commenting out the legend command a legend appears. I want the fit curve and the error bars or the fit curve and the marker plots to both be included as one item in the legend
I would like to get the curves to fit better and remove the markers from withing the error bars. So in the case of the error bars start much closer to y_mid and then run closer to the y_mid on all the other points. In the case of the scatter plot start much closer to [25 500].and the run closer to all the other scatter points. I would also like the best fit curves to extend past the last point if possible. It would be good to change the line style of each curve fit too.
Many thanks
Alex

Accepted Answer

Voss
Voss on 16 Nov 2023
Edited: Voss on 16 Nov 2023
"I would like to ... remove the markers from within the error bars ... I would also like the best fit curves to extend past the last point if possible. It would be good to change the line style of each curve fit too."
  • One way to do all of those things is not to plot the fitobject returned from fit, but instead use its coefficients to calculate your own fit curve and plot that. See x_fit and y_fit in the code below.
"Despite me commenting out the legend command a legend appears."
  • Plotting the fitobject creates a legend. Another advantage of creating your own lines is that you can easily control what goes into the legend (to a degree, see the next item).
"I want the fit curve and the error bars or the fit curve and the marker plots to both be included as one item in the legend"
  • I'm not sure of a way to do that - at least not if you want the data and fit line to be two different colors.
"I would like to get the curves to fit better"
  • Try changing the fit type and/or fit method and/or other fit options.
Strength_MPa = [
20 2880
20 3280
20 3990
1200 2000
1200 2990
1200 3500
1300 2200
1300 2700
1300 3280
1400 1390
1400 1770
1400 2150 ];
Grainsize_nm = [
25 90
1200 120
1300 150
1350 310
1400 450
1500 790 ];
figure1 = figure;
y = reshape(Strength_MPa,3,[]);
x = y(1,1:end/2);
y_min = y(1,end/2+1:end);
y_mid = y(2,end/2+1:end);
y_max = y(3,end/2+1:end);
% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( x, y_mid );
% Set up fittype and options.
ft = fittype( 'power2' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [2450.16071129496 -0.0464507882616668 0.160697077002396];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% plot fit:
x_fit = linspace(1,1600,100);
y_fit = fitresult(x_fit);
plot(x_fit,y_fit,'--r','DisplayName','Strength Fit')
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y_mid', 'Interpreter', 'none' );
grid off
hold on
% plot errorbar:
yyaxis left
errorbar(x,y_mid,y_mid-y_min,y_max-y_mid, ...
'LineStyle','none', ...
'DisplayName','Strength')
ylim([0 4500])
ylabel('Strength [MPa]','Color',[ 0 0 0 ])
ax = gca;
ax.YColor = 'k';
% Fit: 'untitled fit 1'.
x = (Grainsize_nm(:,1));
y = (Grainsize_nm(:,2));
[xData, yData] = prepareCurveData( x, y );
% Set up fittype and options.
ft = fittype( 'exp1' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [58.0338200304954 0.00142172529592695];
% opts.StartPoint = [25 90];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% plot fit:
yyaxis right
x_fit = linspace(1,1600,100);
y_fit = fitresult(x_fit);
plot(x_fit,y_fit,':b','DisplayName','Grain Size Fit')
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y', 'Interpreter', 'none' );
plot(Grainsize_nm(:,1),Grainsize_nm(:,2),'-ro', ...
'MarkerFaceColor','r', ...
'LineStyle','none', ...
'DisplayName','Grain Size')
ylim([0 900])
ylabel('Grainsize [nm]','Color',[ 0 0 0 ])
xlim([0 1600])
ax = gca;
ax.YColor = 'k';
legend
  3 Comments
Voss
Voss on 16 Nov 2023
Edited: Voss on 16 Nov 2023
You're welcome!
Since they can be the same color, what you can do is to create some additional lines (actually one errorbar and one line) which don't show up on the plot but are shown in the legend. See the last few lines of code below.
I'm not familiar enough with fit to say what StartPoint really does, but maybe this helps:
Strength_MPa = [
20 2880
20 3280
20 3990
1200 2000
1200 2990
1200 3500
1300 2200
1300 2700
1300 3280
1400 1390
1400 1770
1400 2150 ];
Grainsize_nm = [
25 90
1200 120
1300 150
1350 310
1400 450
1500 790 ];
figure1 = figure;
y = reshape(Strength_MPa,3,[]);
x = y(1,1:end/2);
y_min = y(1,end/2+1:end);
y_mid = y(2,end/2+1:end);
y_max = y(3,end/2+1:end);
% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( x, y_mid );
% Set up fittype and options.
ft = fittype( 'power2' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [2450.16071129496 -0.0464507882616668 0.160697077002396];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% plot fit:
x_fit = linspace(1,1600,100);
y_fit = fitresult(x_fit);
plot(x_fit,y_fit,'--r')
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y_mid', 'Interpreter', 'none' );
grid off
hold on
% plot errorbar:
yyaxis left
errorbar(x,y_mid,y_mid-y_min,y_max-y_mid, ...
'LineStyle','none', ...
'Color','r')
ylim([0 4500])
ylabel('Strength [MPa]','Color',[ 0 0 0 ])
ax = gca;
ax.YColor = 'k';
% Fit: 'untitled fit 1'.
x = (Grainsize_nm(:,1));
y = (Grainsize_nm(:,2));
[xData, yData] = prepareCurveData( x, y );
% Set up fittype and options.
ft = fittype( 'exp1' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [58.0338200304954 0.00142172529592695];
% opts.StartPoint = [25 90];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% plot fit:
yyaxis right
x_fit = linspace(1,1600,100);
y_fit = fitresult(x_fit);
plot(x_fit,y_fit,':b')
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y', 'Interpreter', 'none' );
plot(Grainsize_nm(:,1),Grainsize_nm(:,2),'bo', ...
'MarkerFaceColor','b')
ylim([0 900])
ylabel('Grainsize [nm]','Color',[ 0 0 0 ])
xlim([0 1600])
ax = gca;
ax.YColor = 'k';
% "dummy" lines for the legend:
h_eb = errorbar(-100,-1,1, ...
'Color','r', ...
'LineStyle','--', ...
'DisplayName','Strength');
h_sc = plot(NaN,NaN,':bo', ...
'MarkerFaceColor','b', ...
'DisplayName','Grain Size');
legend([h_eb h_sc])
A Poyser
A Poyser on 17 Nov 2023
amazing, thanks. Still need to figure out how to control the curve without using the curve fitting tool

Sign in to comment.

More Answers (0)

Categories

Find more on Linear and Nonlinear Regression in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!