How to interpolate data with Gnuplot for further calculations

Viewed 4719

I am (somehow) familiar with the smooth/interpolation techniques in Gnuplot. It seems to me that these interpolations work only for plotting the interpolated values. However, I need the interpolated values for further calculations.

A simple example may illustrate this: Let’s say we are selling a specific item on four days and have the number of sales stored in input_numbers.dat:

# days  |  number_of_sold_items
1   4
2   70
3   80
4   1

Now, I want to plot my income for each day. But the relation between the price per item and the number of sold items is not a simple linear relation, but something complicate which is only known for a few examples – stored in input_price.dat:

# number_of_sold_items  | price_per_item
1      5.00
3      4.10
10     3.80
100    3.00

How can I do something like this (pseudocode):

make INTERPOLATED_PRICE(x) using "input_price.dat"
plot "input_numbers.dat" using 1:($2*INTERPOLATED_PRICE($2))

I can do it by fitting but it is not what I want. The relation of the data is too complicated.

P.S.: I know that the price per item vs the number of items in such an example is more like a step-like function and not smooth. This is just an example for some interpolation in general.

4 Answers

As I understand your question, you are not looking for interpolation but for a lookup-table, i.e. depending on the number of sold items you have a different price.

What you can do with gnuplot is:

  • (mis)using stats to create a lookup-string (check help stats)
  • (mis)using sum to create a lookup-function (check help sum)

Comment: I assume it will be a difference if you for example sell 3 times 1 item on a single day or 1 time 3 items on a single day, because of the graduation of prices. So, I would suggest a different input data format, i.e. with a date. (However, not yet implemented in the example below, but can be done. Then, you can make use of the smooth frequency option.) Some data format, e.g. like this:

# date       sold_items
2022-09-01   1
2022-09-01   1
2022-09-01   1
2022-09-02   3

Script: (works with gnuplot 5.0.0, Jan. 2015)

### implement lookup table
reset session

$SALES <<EOD
# days  |  number_of_sold_items
 1    4
 2   70
 3   80
 4    1
EOD

$PRICE <<EOD
# number_of_sold_items  | price_per_item
   1   5.00
   3   4.10
  10   3.80
 100   3.00
EOD

LookupStr = ''
stats $PRICE u (LookupStr=LookupStr.sprintf(" %g %g",$1,$2)) nooutput
Lookup(v) = (p0=NaN, sum [i=1:words(LookupStr)/2] (v>=real(word(LookupStr,i*2-1)) ? \
             p0=real(word(LookupStr,i*2)) : 0), p0)

set grid x,y
set key noautotitle

set multiplot

    plot $SALES u 1:2 w lp pt 6 lc "dark-grey" ti "sold items", \
             '' u 1:($2*Lookup($2)) w lp pt 7 lc "red" ti "total income"

    # price table as graph inset
    set origin x0=0.41, y0=0.42
    set size   sx=0.30, sy=0.28
    set obj 1 rect from screen x0,y0 to screen x0+sx,y0+sy fs solid noborder lc "white" behind
    set margins 0,0,0,0
    set xrange [:150]
    set yrange [2.5:5.5]
    set xlabel "pieces" offset 0,0.5
    set ylabel "price / piece"
    set logscale x
    plot $PRICE u 1:2 w steps  lc "blue", \
             '' u 1:2 w p pt 7 lc "blue"
unset multiplot
### end of script

Result:

enter image description here

Related