如何使用Gnuplot插入数据以进行进一步计算

时间:2017-09-13 09:50:33

标签: gnuplot interpolation

我(不知何故)熟悉Gnuplot中的平滑/插值技术。在我看来,这些插值仅用于绘制插值。但是,我需要插值来进行进一步的计算。

一个简单的例子可以说明这一点: 假设我们在四天内销售特定商品,并将销售数量存储在input_numbers.dat中:

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

现在,我想绘制每天的收入。但是每件商品的价格与销售商品的数量之间的关系并不是一个简单的线性关系,而是一些复杂的东西,只有一些例子才知道 - 存储在input_price.dat中:

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

我该如何做这样的事情(伪代码):

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

我可以通过拟合来做到,但这不是我想要的。数据的关系太复杂了。

P.S。:我知道每个项目的价格与这样一个例子中的项目数量更像是一个阶梯式的功能,而不是平滑的。这只是一般插值的一个例子。

3 个答案:

答案 0 :(得分:1)

很难证明某些东西不存在,但我非常有信心单凭Gnuplot无法做到这一点,因为:

  • 我对Gnuplot非常熟悉,我知道如果它存在的话。

  • 我找不到任何关于此功能的信息。

  • 完全违背Gnuplot的范例是一个专门用于绘图的工具(拟合已经是边界线)而不是特征数据处理。

答案 1 :(得分:1)

Gnuplot可以这样做:

text = "%f*x + %f"

a = 2
b = 10

eval("f(x) = ".sprintf(text,a,b))

set grid x y
plot f(x)

这基本上意味着可以动态定义复杂的函数:sprintf命令将文本“%f * x +%f”转换为“2.0 * x + 10”,点运算符.连接字符串“f(x)=”和“2.0 * x + 10”,eval命令定义函数f(x) = 2.0*x + 10。可以绘制结果并给出预期的图表:

linear diagram

此行为可用于创建分段插值函数,如下所示:

ip_file = "input_price.dat"
stats ip_file nooutput

n = STATS_records - 1
xmin = STATS_min_x
xmax = STATS_max_x

ip_f = sprintf("x < %f ? NaN : ", xmin)

f(x) = a*x + b # Make a linear interpolation from point to point.

do for [i=0:n-1] {

  set xrange [xmin:xmax]
  stats ip_file every ::i::(i+1) nooutput

  xmintemp = STATS_min_x
  xmaxtemp = STATS_max_x

  set xrange [xmintemp:xmaxtemp]

  a = 1
  b = 1
  fit f(x) ip_file every ::i::(i+1) via a, b

  ip_f = ip_f.sprintf("x < %f ? %f * x + %f : ", xmaxtemp, a, b)

}

ip_f = ip_f."NaN"

print ip_f  # The analytical form of the interpolation function.

eval("ip(x) = ".ip_f)

set samples 1000

#set xrange [xmin:xmax]
#plot ip(x)  # Plot the interpolation function.

unset xrange
plot "input_numbers.dat" using 1:($2*ip($2)) w lp

everystatsfit的组合将范围限制为两个连续的数据点,请参阅help statshelp every。三元运算符?:逐节定义插值函数,请参阅help ternary

这是插值函数的结果分析形式(在一些格式化之后):

x < 1.000000 ? NaN 
    : x < 3.000000 ? -0.450000 * x + 5.450000 
    : x < 10.000000 ? -0.042857 * x + 4.228571 
    : x < 100.000000 ? -0.008889 * x + 3.888889 
    : NaN

这是结果插值函数(由plot ip(x)绘制):

interpolation function

这是在另一个计算中使用插值函数的结果图(plot "input_numbers.dat" using 1:($2*ip($2))):

use interpolation function

我不知道你可以嵌套多少三元运算符的限制以及字符串或函数定义的长度,...

在Debian Jessie上使用Gnuplot 5.0进行测试。

答案 2 :(得分:0)

线性插值不可用,但是如何:

set xr [0:10]
set sample 21

$dat << EOD
0 1
2 2
4 4
6 5
8 4
10 3
EOD
set table $interp
plot $dat us 1:2 with table smooth cspline
unset table
plot $dat w lp, $interp w lp