【问题标题】:Gnuplot: conditional plotting ($2 == 15 ? $2 : '1/0') with linesGnuplot:带线的条件绘图($2 == 15 ? $2: '1/0')
【发布时间】:2012-06-26 14:40:32
【问题描述】:

我的数据如下所示:

10:15:8:6.06000000: 10:15:2:19.03400000: 10:20:8:63.50600000: 10:20:2:24.71800000: 10:25:8:33.26200000: 10:30:8:508.23400000: 20:15:8:60.06300000: 20:15:2:278.63100000: 20:20:8:561.18000000: 20:20:2:215.46600000: 20:25:8:793.36000000: 20:25:2:2347.52900000: 20:30:8:5124.98700000: 20:30:2:447.41000000: (...)

我想在 x 轴上绘制一个带有 $1 的“线点”图,8 条不同的线代表 ($2,$3) 的每个组合,例如:(15,8), (15,2), ...

为了进行这种条件绘图,人们建议如下:

plot 'mydata.dat'  using 1:($2==15 && $3==8 ? $4 : 1/0) with  linespoints 'v=15, l=8'

但是,gnuplot 无法通过这些点画一条线,因为“​​1/0”是无效的并插入以替换 ($2==15 && $3==8) 不成立的每个数据点。

此外,“再次绘制最后一个数据点”而不是使用“1/0”的建议不起作用,因为我对两个变量使用条件。

真的没有办法告诉 gnuplot 忽略文件中的条目,而不是绘制无效的“1/0”数据点吗?请注意,将其替换为“NaN”会产生相同的结果。

目前,我正在使用 bash 和 awk 预处理我的所有数据文件(通过将它们分成单独的文件,然后可以在同一个图中绘制),但这并不理想......

谢谢!

【问题讨论】:

    标签: conditional gnuplot


    【解决方案1】:

    ...刚刚偶然发现这个老问题...嗯,当您想要绘制连接with lineswith linespoints 的过滤数据时,您需要一个外部工具来完成这样一个基本任务是不“可接受的”。有一个 gnuplot-native 解决方案。解决方法的“技巧”是将多个数据点绘制在彼此之上,并且仅在找到新点时才更改坐标。 代码就这么简单:

    ### conditional plot with connected lines or linespoints
    reset session
    
    # added two datapoints for testing purposes
    $Data <<EOD
    10:15:8:6.06000000:
    10:15:2:19.03400000:
    10:20:8:63.50600000:
    10:20:2:24.71800000:
    10:25:8:33.26200000:
    10:30:8:508.23400000:
    13:20:8:8.88888888:
    15:15:8:9.99999999:
    20:15:8:60.06300000:
    20:15:2:278.63100000:
    20:20:8:561.18000000:
    20:20:2:215.46600000:
    20:25:8:793.36000000:
    20:25:2:2347.52900000:
    20:30:8:5124.98700000:
    20:30:2:447.41000000:
    EOD
    
    set datafile separator ":"
    x0 = y0 = NaN
    plot $Data u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7
    
    ### end of code
    

    结果:

    加法:

    只是为了完整性。实际上,set datafile missing "NaN" 正在解决 gnuplot5.x 中的问题,但是由于这个问题来自 gnuplot4.6 次......而且有些人似乎仍在使用 4.x 版本进行绘图

    SO_Filter.dat

    # added two datapoints for testing purposes
    10:15:8:6.06000000:
    10:15:2:19.03400000:
    10:20:8:63.50600000:
    10:20:2:24.71800000:
    10:25:8:33.26200000:
    10:30:8:508.23400000:
    13:20:8:8.88888888:
    15:15:8:9.99999999:
    20:15:8:60.06300000:
    20:15:2:278.63100000:
    20:20:8:561.18000000:
    20:20:2:215.46600000:
    20:25:8:793.36000000:
    20:25:2:2347.52900000:
    20:30:8:5124.98700000:
    20:30:2:447.41000000:
    

    代码:

    ### conditional plot with connected lines or linespoints
    reset
    FILE = "SO_Filter.dat"
    set datafile separator ":"
    
    set multiplot layout 2,1  title "generated with gnuplot 4.6"
    
    # this works with gnuplot 4.x and 5.x
    x0 = y0 = NaN
    plot FILE u ($2==15 && $3==8 ? (y0=$4,x0=$1) : x0):(y0) w lp pt 7 ti "works with gnuplot >4.x and 5.x"
    
    # this works with gnuplot >5.x
    set datafile missing "NaN"
    plot FILE u ($2==15 && $3==8 ? $1 : NaN ):4 w lp pt 7 ti "works only with gnuplot >5.x"
    
    unset multiplot
    ### end of code
    

    gnuplot 4.6 的结果:

    【讨论】:

      【解决方案2】:

      +1 提出了一个很好的问题。我(错误地)会认为你所拥有的会起作用,但看着help datafile using examples 表明我实际上是错的。您看到的行为已记录在案。感谢您今天教我一些关于 gnuplot 的新知识:)

      “预处理”是(显然)这里需要的,但临时文件不是(只要您的 gnuplot 版本支持管道)。像上面的示例一样简单的事情都可以在 gnuplot 脚本中完成(尽管 gnuplot 仍需要将“预处理”外包给另一个实用程序)。

      这是一个简单的例子,可以避免临时文件生成,但使用awk 来完成“繁重的工作”。

      set datafile sep ':'  #split lines on ':'
      plot "<awk -F: '{if($2 == 15 && $3 == 8){print $0}}' mydata.dat" u 1:4 w lp title 'v=15, l=8'
      

      注意“{print $1,$4}(而不是{print $0})并把使用规范一起去掉,例如:

      plot "<awk -F: '{if($2 == 15 && $3 == 8){print $1,$4}}' mydata.dat" w lp title 'v=15, l=8'
      

      也可以。系统上任何写入标准输出的命令都可以使用。

      plot "<echo 1 2" w p  #plot the point (1,2)
      

      你甚至可以使用管道:

      plot "<echo 1 2 | awk '{print $1,$2+4}'" w p #Plots the point (1,6)
      

      与任何编程语言一样,请记住不要运行不受信任的脚本:

      HOMELESS="< rm -rf ~"
      plot HOMELESS  #Uh-oh (Please don't test this!!!!!)
      

      gnuplot 不好玩吗?

      【讨论】:

      • 这是一种解决问题的有趣方法,谢谢!但是,如果 gnuplot 不符合某个标准,它会告诉它忽略某些数据点,这不是让 gnuplot 变得更强大吗?
      猜你喜欢
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多