Problems to fit with gnuplot and non-linear function - linux

I have this set of data that want to fit with gnuplot using the function f(x) = exp(A+ B/(x-x0)) where A,B and x0 are my set of parameters to fit
# x f(x)
0.382 8.29023731095968
0.509 6.36124122026352
0.637 4.66938977764103
0.764 3.3194714217965
0.891 2.15140777817893
1.019 1.15428884806615
1.146 0.262232461832655
I have try it with
fit log(f(x)) 'data.dat' using 1:(log($2)) via A, B, x0
also have defined the function as f(x) = A+ B/(x-x0) and tried with
fit f(x) 'data.dat' using 1:(log($2)) via A, B, x0
and then plot exp(f(x))
The code works but the fitted parameters are not fine, because when I plot the curve and the points together not make sense. Is this fit too complicate for gnuplot?

Fitting can fail if you have an inappropriate function or if you have starting values which might make it difficult for the fitting procedure to converge.
In your case, I guess x0 is an important parameter. You should help the gnuplot fitting algorithm a little to have a chance to find reasonable values. Here, I guess x0=1.5 is a reasonable starting value. If this is not sufficient and if your model permits you might want to add additional variables or terms to get a better fit.
Code:
### fitting with appropriate starting values
reset session
$Data <<EOD
0.382 8.29023731095968
0.509 6.36124122026352
0.637 4.66938977764103
0.764 3.3194714217965
0.891 2.15140777817893
1.019 1.15428884806615
1.146 0.262232461832655
EOD
A = 1
B = 1
x0 = 1.5
f(x) = exp(A + B/(x-x0))
set fit nolog
fit f(x) $Data u 1:2 via A,B,x0
plot $Data u 1:2 w lp pt 7 ti "Data",\
f(x) w l lc rgb "red" ti "Fit"
### end of code
Result:
Final set of parameters Asymptotic Standard Error
======================= ==========================
A = 4.61445 +/- 0.3907 (8.466%)
B = 3.57094 +/- 0.8876 (24.86%)
x0 = 1.80616 +/- 0.1371 (7.593%)

Related

How to fit a logarithmic function with gnuplot?

I have the following data and want to fit a function with gnuplot. It seems that the function is:
f(x) = 0.000855*(1 + b*log(x/a)) with b=0.45 and a=32.23
fits with the data. I used the following command in gnuplot but I couldn't fit this function with the data.
6.77 0.000165774
8.13 0.00034866
9.48 0.000440373
10.83 0.000473223
16.25 0.000589812
18.28 0.000629904
20.31 0.000661883
I used the following command:
p "./data.txt" u 1:2
f(x) = 0.000855*( 1 + b*log(x/a))
fix f(x) "data.txt" using 1:2 via b,a
p "./data.txt", f(x)
could you please suggest any more functions?
Thanks in advance,
How do you know that your function should fit the data and from where do you get the values a,b?
In general, you can shift and scale basic functions, e.g. like log().
So, if you think log(x) is a suitable function to describe your data then try to shift and scale it.
Shift x by x0, shift y by y0 and scale with some factor a.
Altogether:
f(x) = a*log(x-x0) + y0
In the script example below it seems that you don't even need approximate starting values to let the fit converge.
However, the mathematical description of your system should give you the function. Without knowing your system, nobody can tell whether f(x) is an appropriate function to fit your data.
Script:
### fitting a log function
reset session
$Data <<EOD
6.77 0.000165774
8.13 0.00034866
9.48 0.000440373
10.83 0.000473223
16.25 0.000589812
18.28 0.000629904
20.31 0.000661883
EOD
f(x) = a*log(x-x0) + y0
set fit nolog
fit f(x) $Data u 1:2 via a,x0,y0
set key top left
plot $Data u 1:2 w lp pt 7, \
f(x) w l lc "red", \
0.000855*(1 + 0.45*log(x/32.23)) w l dt 3 lc "blue" ti "your guess"
### end of script
Result:
Final set of parameters Asymptotic Standard Error
======================= ==========================
a = 0.000153601 +/- 8.592e-06 (5.594%)
x0 = 6.17491 +/- 0.1102 (1.785%)
y0 = 0.000245976 +/- 1.982e-05 (8.057%)

Gnuplot with Errorbars and line of regression

I want to graph some values with errorbars but it somehow doesnt work. Can you help me please?
431.00E12 0.69 47.00E5
567.00E12 1.10 58.00E5
662.00E12 1.75 67.00E5
watched a lot of videos and tutorials and did exactly what they did but it doesnt work.. The part with Regression and so on worked fine but now I want those error bars horizontally. My textfile is in this order:
x-Value y-Value DeltaX
The DeltaX should be the Errorbar so the errorbar schould look like this: at point x, the errorbar has length from x+-DeltaX.
Could you please tell me the code that combines the regression line and the Errorbars?
plot "/Users/amar/Desktop/dgd.txt" using 1:2:3 with errorbars, f(x)
Check help xerrorbars.
A delta x which is 8 orders of magnitude smaller than the x-value will be difficult to see as errorbar. Just to demonstrate xerrorbars, I changed it to a similar order of magnitude.
With the following code:
### xerrorbars
reset session
$Data <<EOD
431.00E12 0.69 47.00E12
567.00E12 1.10 58.00E12
662.00E12 1.75 67.00E12
EOD
set key left
f(x) = a*x + b
a = 1e-15 # some initial guesses
b = -1
set fit nolog brief
fit f(x) $Data u 1:2 via a,b
plot $Data u 1:2:3 with xerrorbars pt 7 lc rgb "red", \
f(x) title sprintf("f(x) = %g * x + %g",a,b)
### end of code
You'll get:

fitting sub-range on time data in gnuplot

Let me start by saying that I am working on:
$ gnuplot --version
gnuplot 5.2 patchlevel 2
I would like to plot and fit date/time data in gnuplot and have the fit only performed and subsequently displayed on a sub-range of the plot.
Example data that I played with can e.g. be found here.
EDIT: I realized that the data in the file don't match the timefmt signature, I added a /06 to each line so that the point would be drawn in the middle of the year which allowed to nicely plot it together with also monthly data from the same source.
I can get the desired result with the code below where I plot three functions, one over the full range of the plot and two others both of which only cover part of the date range.
set key left
set yrange[-0.75:1.0]
set xdata time
set timefmt '%Y/%m'
r=10e-10
e(x) = r*x+s
fit e(x) 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 via r,s
a=10e-10
f(x) = a * x + b
set xrange ["1970/06":"2018/06"]
fit f(x) 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 via a,b
g(x) = ( x > "1970/06" ) ? f(x) : 1/0
set xrange ["1850/06":"1970/06"]
c=9.24859e-11
h(x) = c * x + d
fit h(x) 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 via c,d
i(x) = ( x < "1970/06" ) ? h(x) : 1/0
set xrange ["1849/06":"2018/06"]
set term png size 1500,1000
set output 'annual_average_with_fit.png'
plot 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 with lp lw 2 t'annual avg (decadally smoothed)', e(x) t'full range fit' lw 2, i(x) t'1850-1970 fit' lw 2, g(x) t'1970-2018 fit' lw 2
which yields this plot
This is all good and well, but (and this is where the question comes in) in principle I should be able to achieve the same result also by other means.
First: I restrict the range of the file data to a certain range to fit it only on that range. In principle I should be able to do the same using this (type of) syntax:
fit ["1970/06":"2018/06"] f(x) 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 via a,b
which however gives
Read 168 points
Skipped 168 points outside range [x=1970:2018]
[...] No data to fit
which seems weird given that the set xrange clearly has the desired effect.
Secondly trying to restrict the plotting of the curve to the fit range with
plot 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt' using 1:2 with lp lw 2 t'annual avg (decadally smoothed)', ["1970/06":"2018/06"] f(x) t''
does not plot the function at all.
I might be overlooking something very basic, but having tried various things I don't see what it is
The following (a bit cleaned up) code should do what you want (tested with gnuplot 5.2.5).
I guess the problem is that you tried to fit a range ["1970/06":"2018/06"], but your data is only until 2017. So better leave it open, e.g. ["1970/06":] or ["1970/06":*].
edit: added a limited range fit i(x)
reset session
set term png size 1500,1000
set output 'annual_average_with_fit.png'
set key left
set yrange[-0.75:1.0]
set xdata time
set timefmt '%Y/%m'
set format x '%Y'
FILE = 'HadCRUT.4.6.0.0.annual_ns_avg_smooth.txt'
r=10e-10
f(x) = r*x+s
fit [*:*] f(x) FILE using 1:2 via r,s
c=9.24859e-11
g(x) = c * x + d
fit [*:"1970/06"] g(x) FILE using 1:2 via c,d
a=10e-10
h(x) = a * x + b
fit ["1970/06":*] h(x) FILE using 1:2 via a,b
p=1e-9
i(x) = p * x + q
fit [strptime("%Y/%m", "1910/06"):strptime("%Y/%m", "1945/06")] i(x) FILE using 1:2 via p,q
set xrange [*:*]
plot FILE using 1:2 with lp lw 2 t'annual avg (decadally smoothed)', \
f(x) t 'full range fit' lw 2, \
[:"1970/06"] g(x) t '1850-1970 fit' lw 2, \
["1970/06":] h(x) t '1970-2018 fit' lw 2,\
[strptime("%Y/%m", "1910/06"):strptime("%Y/%m", "1945/06")] i(x) t '1910-1945 fit' lw 2
set output
Output:

Gnuplot: Fitting asymptotic curve to data

I am trying to fit an asymptotic curve to my data using gnuplot. It is a dataset showing reaction time results over a testing period. I have been able to plot the data and fit a straight line through it using the following code.
f(x) = a*x + c;
fit f(x) 'ReactionLearning.txt' using 1:2 via a,c
plot 'ReactionLearning.txt' using 1:2 with points lt 1 pt 3 notitle, \
f(x) with lines notitle
Which gives the following result:
http://imgur.com/PlQmalX.jpg
However, as this is supposed to show a learning effect, an asymptotic curve would make a lot more sense because the increase in performance caused by a learning effect will eventually stop, making the line even out.
From what I understand asymptotic cuves are created with the f(x) = 1/x. So I changed my code to be
f(x) = 1/(a*x)
fit f(x) 'ReactionLearning.txt' using 1:2 via a
plot 'ReactionLearning.txt' using 1:2 with points lt 1 pt 3 notitle, \
f(x) with lines notitle
However, I get this output: http://imgur.com/PimTa1T
Could someone explain what I am doing wrong here?
Thanks
There are many curves that show an asymptotic behavior, and 1/x is probably not the one that comes most often when describing physical or biological processes. Usually, these processes might show some sort of exponential decay. With the data that you show I don't think you can conclude anything about which model you should use, other than "it decays". If you already know what is the functional behavior you expect, that makes things different. That said, the general form of your 1/x curve should be f(x) = a/(x-x0) + c, which will probably give you some meaningful results when you fit to it:
f(x) = a/(x-x0) + c
fit f(x) "data" via a,c,x0
Since fitting might show instabilities for this kind of function if the initial values are bad, you should/might need to provide sensible initial values or reformulate the problem as a linear relation. You can do the latter by a change of variable y = 1/(x - x0) and do the fitting for different values of x0. Record the error in the fit (which is output by gnuplot) for each of them and see how the error gets minimized as a function of x0: it should be quadratic about the optimum value. Something like this:
f(x) = a*x + c
x0 = 1. # give some value for x0
fit f(x) "data" u (1./($1-x0)):2 via a,c # record fit errors for a and c
x0 = 3. # give some other value for x0
fit f(x) "data" u (1./($1-x0)):2 via a,c # record fit errors for a and c

How can i reduce the linear fit plot to a certain interval?

what i do is to fit two linear function´s to my data.
i know how to select the data for the various fitting functions. My problem is that i want the fitted lines only to be plottet in a certain interval.
What i did till now:
f(x) = a*x + b; fit [800:1250][-2:8] f(x) 'Daten.txt' u 1:2 via a,b
g(x) = c*x + d; fit [1258:1650][-2:8] g(x) 'Daten.txt' u 1:2 via c,d
plot "Daten.txt" u 1:2 w l, f(x) t title_f(a,b), g(x) t title_g(c,d)
it results in
a picture i´m not allowed to post...
How can i make the green fittin-line only to run from 800-1200 and the blue fitting-line from 1100-end?
The syntax
plot [xmin:xmax] f(x)
(the same as for fit) restricts the plot to a certain range. So, you could do something like
plot "Daten.txt" u 1:2 w l, [800:1200] f(x) t title_f(a,b), [1100:] g(x) t title_g(c,d)

Resources