首页 文章

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

提问于
浏览
2

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

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

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

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

# 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 回答

  • 1

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

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

    • 我找不到关于这样一个功能的任何信息 .

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

  • 0

    Gnuplot可以做这样的事情:

    text = "%f*x + %f"
    
    a = 2
    b = 10
    
    eval("f(x) = ".sprintf(text,a,b))
    
    set grid x y
    plot f(x)
    

    这基本上意味着可以动态定义复杂的函数: sprintf 命令将文本"%fx + %f"转换为"2.0x + 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进行测试 .

  • 1

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

    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
    

相关问题