Fitting data with formula

Gnuplot is capable to fit given data with functions given as formulas. This notebook contain several examples about how to fit data with GnuplotRB.

First lets prepare some data:

In [1]:
require 'daru'
require 'gnuplotrb'
include GnuplotRB
include Fit

rows = (1..30).map do |i|
  [i**2 * (rand(4) + 3) / 5, rand(70) + 1]
end
df = Daru::DataFrame.rows(rows, order: [:Value, :Error], name: 'Confidence interval')

random_points = Plot.new(
  [df[:Value], with: 'lines', title: 'Average value'],
  [df, with: 'err']
)
Out[1]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -200 0 200 400 600 800 1000 1200 0 5 10 15 20 25 30 Average value Average value Confidence interval Confidence interval

And now lets try to fit it with some function.

First parameter of #fit is data (you can use here Datablock, Dataset or any other object out of which Datablock may be constructed). Special options are function and initials, other options (such as using) may be found in gnuplot docs. Be careful: you should give initial value for each coefficient used in formula.

Return value is the following hash:

{
  :formula_ds => #<dataset with formula which fits given data>,
  :coefficients => #<hash of calculated coefficients>,
  :deltas => #<hash of possible deltas for coefficients>,
  :data => #<given data>
}
In [2]:
some_poly = fit(df, function: "a*x**3 + b*x + c", initials: {a: 1, b: 1, c: 1})
some_poly[:coefficients]
Out[2]:
{:a=>0.0271674, :b=>8.64614, :c=>-6.69375}
In [3]:
some_poly[:formula_ds].data
Out[3]:
" 0.0271674*x**3 + 8.64614*x + -6.69375 "
In [4]:
some_poly[:formula_ds]
Out[4]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -150 -100 -50 0 50 100 150 -10 -5 0 5 10 Fit formula Fit formula
In [5]:
random_points << some_poly[:formula_ds]
Out[5]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -200 0 200 400 600 800 1000 1200 0 5 10 15 20 25 30 Fit formula Fit formula Average value Average value Confidence interval Confidence interval

You can find more information about how gnuplot's fitting work in gnuplot doc.

Default fittings

Polynomial:

In [6]:
poly = fit_poly(df)
random_points.add_dataset(poly[:formula_ds])
Out[6]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -200 0 200 400 600 800 1000 1200 0 5 10 15 20 25 30 Fit formula Fit formula Average value Average value Confidence interval Confidence interval

Be default polynomial degree is 2 but you can set it:

In [7]:
frames = (2..9).map { |i| random_points.add_dataset(fit_poly(df, degree: i)[:formula_ds].options(title: "Fit (degree #{i})", lw: 2)) }
Animation.new(*frames, animate: { delay: 150 } )
Out[7]:

You can also fit data with exp, sin and log like this:

In [8]:
exp = fit_exp(df)
random_points.add_dataset(exp[:formula_ds])
Out[8]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -200 0 200 400 600 800 1000 1200 0 5 10 15 20 25 30 Fit formula Fit formula Average value Average value Confidence interval Confidence interval

And set ranges for fitting:

In [9]:
ranged_poly = fit_poly(df, degree: 4, term_options: { xrange: 0..15})
random_points.add_dataset(ranged_poly[:formula_ds]).xrange(0..15)
Out[9]:
Gnuplot Produced by GNUPLOT 5.0 patchlevel rc2 -50 0 50 100 150 200 250 300 350 0 2 4 6 8 10 12 14 Fit formula Fit formula Average value Average value Confidence interval Confidence interval