如何使用 gnuplot 重新采样或插值数据?

问题描述 投票:0回答:1

在某些情况下,您可能需要对数据重新采样。如何使用 gnuplot 独立于平台来完成此操作?以下是一种尝试。

数据集

$Dummy
包含插值,但是,有很多不必要的行包含
NaN
。数据集
$DataResampled
最终包含了所需的数据。

我的问题是:这可以更简单、更快地完成吗?

脚本:


### resampling data with linear interpolation
reset session

$Data <<EOD
0   1
1   4
2   10
5   15
10  5
20  11
EOD

# get the x-range
stats $Data u 1 nooutput
MinX = STATS_min
MaxX = STATS_max
Resamples=20
# or alternatively fix the step size 
# StepSize=1
# Resamples = int(MaxX-MinX)/StepSize+1

Interpolate(xi) = y0 + (y1-y0)/(x1-x0)*(xi-x0) 
x1=y1=NaN

# resample the data
set print $DataResampled
set table $Dummy
do for [i=1:Resamples] {
    xi = MinX + (i-1)*(MaxX-MinX)/(Resamples-1)
    Flag=0
    plot $Data u (x0=x1, x1=$1, y0=y1, y1=$2,\
        (xi>=x0 && xi<=x1 && Flag==0 ? (Flag=1, yi=Interpolate(xi), xi) : NaN)): \
        (Flag==1 ? yi : NaN) with table
    print sprintf("%g\t%g",xi,yi)
}
unset table
set print

set xrange[-1:21]
plot $Data u 1:2 w lp pt 6 ps 2 lc rgb "black" t "original data",\
     $DataResampled u 1:2 w lp pt 7 lc rgb "web-green" t "resampled with linear interpolation",\
     $Dummy u 1:2 w impulses lc rgb "red" not
### end of script

结果:

gnuplot linear-interpolation
1个回答
0
投票

序言:我知道 gnuplot 希望成为一个绘图程序,而不是一个数据分析或数据处理工具。然而,一些数据处理函数会很有用,例如就像数据的线性插值/重采样一样。
在 gnuplot 中,有一些平滑选项实现了检查

help smooth
,但这些选项用于平滑具有许多数据点的噪声数据。 有:
smooth bezier
smooth cplines
smooth acsplines
smooth mcsplines
smooth sbeziers
,以及从 gnuplot 5.5 开始。
smooth path
用于沿路径插值。像
smooth linear
这样的东西还不存在(尚),并且似乎 不够有趣 无法实现。

一个应用示例:
您拥有来自光谱仪的光谱原始数据,这些数据具有奇数间隔的波长,例如

380.71, 383.53, 386.21, ...
并且您在波长
380, 382, 384, 386, 388, ...
处有一个滤波器函数,并且您希望为每个波长乘以该数据。因此,您需要使两个数据集的 y 值具有相同的 x 值。 当然,您可以使用外部程序来完成。

但是,如果它不是太复杂也不是太低效,为什么不在 gnuplot 中进行呢? 所以,我认为以下脚本是一种快速的gnuplot-only数据线性重采样/插值的方法。

评论:

  • 可以使用具有任意、不规则 x 位置的文件来代替数据块
    $InterpolX
  • 该脚本“严重”滥用了
    smooth zsort
    选项
    来完成工作。
  • 它使用存储在第三列中的两个原始数据点之间的角度(检查
    help atan2
    )来计算稍后的中间点。数据将通过
    smooth zsort
  • 按 x 值排序
  • 角度范围从
    -pi
    +pi
    (或
    -180
    +180
    度),具体取决于
    set angles {degrees | radians}
    设置。因此,变量
    OoR
    (=超出范围)被任意设置为
    999
    ,以区分原始点和需要插值的点。
  • 变量
    p
    决定是否应包含原始数据点
  • 对于 2000 个重新采样的数据点,OP 问题中的脚本大约需要 80 秒,而以下脚本在我的旧笔记本电脑上大约需要 0.06 秒。由于一些奇怪的原因,仅在 gnuplot 5.4.1 和 5.4.8 中需要 0.23 秒,但测试的其他版本大约需要 0.06 秒。

数据:

SO54362441.dat

0   1
1   4
2   10
5   15
10  5
20  11

脚本:(适用于 gnuplot>=5.4.0 2020 年 7 月)

### resampling of data via linear interpolation
reset session

FILE = "SO54362441.dat"

set table $InterpolX
    set samples 20    # set number of samples
    plot [0:20] '+' u 1 w table
unset table

set table $Temp
    plot x1=y1=NaN FILE u (x0=x1,x1=$1,x0):(y0=y1,y1=$2,y0):(atan2(y1-y0,x1-x0)) w table, \
         '+' every ::::0 u (x1):(y1):(0) w table, \
         OoR=999 $InterpolX u 1:(0):(OoR) w table
set table $Temp2
    plot $Temp u 2:3:1:1 smooth zsort lc var
set table $Interpolated
    p = 0    # include original datapoints? 0=no, 1=yes
    plot x1=y2=xb=yb=NaN $Temp2 u (x0=x1, x1=$3, y1=$1, a1=$2, \
         a1==OoR ? ( y2=yb+(x1-xb)*tan(ab) ) : \
         (ab=a1, xb=x1, yb=y1, y2 = x0==x1 ? y1 : p ? yb : ''), x1) : (y2) w table
unset table

plot FILE          u 1:2 w lp pt 7     lc "black"     ti "Original data", \
     $Interpolated u 1:2 w impulses    lc "web-green" notitle, \
     $Interpolated u 1:2 w p pt 6 ps 2 lc "red"       ti "Interpolated"
### end of script

结果:

© www.soinside.com 2019 - 2024. All rights reserved.