【问题标题】:Scaling the values to plot a graph using gnuplot使用 gnuplot 缩放值以绘制图形
【发布时间】:2012-06-17 08:52:57
【问题描述】:

我有一个以下格式的文本文件。第一列表示具有非常高分辨率的时间戳。第二个数字表示序列号。我想在这两个值之间绘制一个图表。即序列号随时间的变化。为此,我想缩放序列号和时间戳。时间戳可以通过从剩余时间戳中减去第一个时间戳来缩放。序列号也应该以相同的方式缩放。但是当缩放时,序列号可以为负数值。如何使用 awk 编写 bash 脚本来实现这一点。此文件名为 print_1010171.txt。请注意,我确实有许多相同格式的文件。所以我希望脚本具有通用性。

5698771509078629376     1133254688
5698771509371165696     1150031904
5698771510035551232     1150031904
5698771510036082688     4170258464
5698771510036715520     2895583264
5698771510037202176     1620908064
5698771510037665280     346232864
5698771510038193664     3366459424
5698771510332259072     2091784224
5698771510332816128     817109024
5698771510333344512     3837335584
5698771510339882240     2562660384
5698771510340411392     1287985184
5698771510340939776     13309984
5698771510348048896     3033536544
5698771510348577280     1758861344
5698771510349228800     484186144
5698771510632804864     3504412704
5698771510633441792     2229737504
5698771510634390272     955062304
5698771510638858496     3975288864
5698771510639347712     2700613664
5698771510642663168     1425938464
5698771510643387136     134486304
5698771510643808768     3154712864
5698771510648858368     1880037664
5698771510649410560     605362464
5698771510655600384     3625589024
5698771510656128768     2350913824
5698771510656657408     1076238624

【问题讨论】:

    标签: awk gnuplot


    【解决方案1】:

    与 Dennis Williamson 的解决方案非常相似——这应该更有效(但可能你不会注意到)并且它也会默默地忽略空白行(另一种解决方案将为空白行提供非常大的负数)。

    #script coolscript.gp
    if(!exists("DATAFILE")) DATAFILE='test.dat'
    EXT_INDEX=strstr(DATAFILE,'.txt')  #assume data has a .txt extension.
    set term post enh color
    set output DATAFILE[:EXT_INDEX] . '.ps'  #gnuplot string slicing and concatenation
    plot "< awk 'BEGIN{getline; header_col1=$1; header_col2=$2 }{if(NF){print $1-header_col1,$2-header_col2}}' ".DATAFILE using 1:2
    

    您绝对可以使用全 gnuplot 解决方案来做到这一点。 (请参阅@andyras 的好解决方案和他链接到的我的答案)。这个(替代)解决方案的工作原理是读取 awk 中的第一行并将变量 header_col1header_col2 与第 1 列和第 2 列中的数据一起分配。然后,只要行不为空。

    请注意,可以使用以下命令从命令行调用此解决方案:

    gnuplot -e "DATAFILE='mydatafile.txt'" coolscript.gp
    

    不幸的是,引号是必需的,因为 gnuplot 需要它们,这意味着如果你在 shell 循环中使用它,你肯定应该在外面使用双引号,就像我展示的那样。

    for FILE in *.dat; do
       gnuplot -e "DATAFILE='${FILE}'" coolscript.gp
    done
    

    【讨论】:

      【解决方案2】:
      awk 'NR == 1 {basets = $1; baseseq = $2} {print $1 - basets, $2 - baseseq}' inputfile
      

      或者,如果您不想输出初始的一对零:

      awk 'NR == 1 {basets = $1; baseseq = $2; next} {print $1 - basets, $2 - baseseq}' inputfile
      

      【讨论】:

        【解决方案3】:

        这是一个 bash 包装脚本,它应该可以满足您的需求:

        #!/bin/bash
        
        gnuplot << EOF
        set terminal png truecolor size 800,600
        set output 'plot_$1.png'
        
        firstx=0
        offsetx=0
        funcx(x)=(offsetx=(firstx==0)?x:offsetx,firstx=1,x-offsetx)
        firsty=0
        offsety=0
        funcy(x)=(offsety=(firsty==0)?x:offsety,firsty=1,x-offsety)
        
        plot '$1' u (funcx(\$1)):(funcy(\$2))
        EOF
        

        要使用脚本,请将要绘制的文件的名称作为参数提供:

        $ myscript.sh print_1010171.txt
        

        我修改了here 给出的答案以适应两个变量。如果您想从所有数据中减去最小值而不是第一个,请参阅该答案。

        【讨论】:

        • 这里不需要echo
        • 此外,分号无关紧要,您的输出文件将命名为plot_print_stuff.txt.png。您可能可以使用strstr 函数和字符串切片来切断.txt 扩展名(如果您知道数据文件具有.txt 扩展名)。 (否则,很好的答案;)+1
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-29
        • 1970-01-01
        相关资源
        最近更新 更多