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

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)

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%)

Problems to fit with gnuplot and non-linear function

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%)

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:

How to restrict yrange for fit in gnuplot

I used the following scripts for plotting and fitting.
Data set:
2.474 2.659
0.701 2.637
0.582 2.643
0.513 2.666
0.403 2.639
0.308 2.615
0.218 2.561
0.137 2.537
Script:
reset
set key bottom right
f(x) = a*atan(x/b); a = 2.65; b = 2.5
fit f(x) 'test.txt' u 1:2 via a,b
plot 'test.txt' u 1:2 w p not, f(x) t 'f(x)'
The plot looks like this:
I am trying to restrict it between min_y and max_y. The following intuitive code failed horribly,
fit [y=2.537:2.659] f(x) 'test.txt' u 1:2 via a,b
Any suggestion on restriction would be highly appreciated! Thanks!
The range option only specifies which input points should be used, not restricting the output. So far as I can see from the manual, restrictions on the output value of f(x) aren't really possible (and so far as I can see from the problem, not really desirable).
You should be able also to do it simply by defining a fit range [][].
The following code works also with gnuplot4.6 which was the version in 2014.
"Data.dat":
1 2
2 3
3 4
1 9
2 8
3 7
Code:
### fit with limited y-range
reset
set xrange[0:10]
set yrange[0:10]
f(x) = a*x + b
set multiplot layout 3,1
fit [*:*][0:5] f(x) "Data.dat" u 1:2 via a,b
plot "Data.dat" u 1:2 w p pt 7 lc rgb "red" not,\
f(x) t sprintf("Fitrange: [*:*][0:5]\nf(x) = %g*x + %g",a,b)
fit [*:*][5:10] f(x) "Data.dat" u 1:2 via a,b
plot "Data.dat" u 1:2 w p pt 7 lc rgb "red" not,\
f(x) t sprintf("Fitrange: [*:*][5:10]\nf(x) = %g*x + %g",a,b)
fit [*:*][0:10] f(x) "Data.dat" u 1:2 via a,b
plot "Data.dat" u 1:2 w p pt 7 lc rgb "red" not,\
f(x) t sprintf("Fitrange: [*:*][0:10]\nf(x) = %g*x + %g",a,b)
unset multiplot
### end of code
Result:
This is an old question, but I arrived here looking for a solution to a similar problem. The answer is to use the stats command:
stats 'test.txt'
This will analyze, by default, the y data and set a bunch of STATS_* variables, which you can use in your fit statement along with the ternary operator:
fit f(x) 'test.txt' u 1:($2 >= STATS_min && $2 <= STATS_max ? $2 : NaN) via a,b
You can also add a using clause to the stats statement to further filter the data to match your fit statement, if needed.

Resources