Gnuplot using修饰符语法问题及y值未定义异常咨询
测试数据:
x y 0 1.1 1 1.0 2 1.3 3 1.4 4 0.9
基础正常场景:执行命令 plot a=0 'data.txt' using 1:(a=a+$2,a) with linespoints 可正常实现列2的累加绘图,执行 print a 返回预期值5.7。
以下是三类异常的语法层面原因:
1. x侧使用表达式后print a返回NaN
命令:plot a=0 'data.txt' using (a=a+$2,$1):2 with linespoints
绘图正常但print a返回NaN。
原因:Gnuplot处理绘图命令时,会对每个数据点的x、y表达式进行多次求值(比如计算绘图范围、实际绘制点等)。当累加表达式放在x侧时,最后一次求值可能发生在无数据点的上下文(所有点处理完后的收尾步骤),此时$2未绑定有效数据,执行a=a+$2会让a变为NaN。而y侧表达式的最后一次有效求值停留在最后一个数据点,不会触发无数据的情况。
2. x侧加括号后提示“all points y value undefined!”
命令:plot a=0 'data.txt' using ($1):(a=a+$2,a) with linespoints
触发“all points y value undefined!”错误。
原因:这是Gnuplot求值顺序与变量初始化时机的问题。当x侧使用($1)这种显式括号包裹的表达式时,Gnuplot会优先对x表达式做预求值(用于确定绘图范围),此时变量a的初始值0尚未正确传递到y表达式的上下文,或者预求值阶段单独执行y表达式时,$2还未绑定数据,导致a=a+$2得到undefined,最终所有y值被判定为未定义。而原命令x侧用1(直接列引用)时,预求值逻辑不同,不会触发该问题。
3. x侧使用三元运算符时提示y值未定义
命令:plot a=0 'data.txt' using ($1>1 && $1<4? $1:1/0):(a=$2+a,a) with linespoints
触发y值未定义错误,将三元运算符移至y侧则正常工作。
原因:Gnuplot处理包含1/0(代表undefined)的x表达式时,会跳过对应数据点,且不会执行该点的y表达式。当x侧三元运算符过滤部分点时,累加变量a仅在x值有效的点更新,但Gnuplot的预检查逻辑会遍历所有点,若存在x值为undefined的点,对应的y表达式求值会失败(预检查时可能单独评估y表达式,或因x被过滤导致y表达式未执行,进而被判定为undefined)。将三元运算符移至y侧时,所有点的x表达式均有效,y侧的1/0仅让对应点不显示,但累加逻辑会在所有点执行,不会触发全局y值未定义提示。
内容的提问来源于stack exchange,提问作者Galileu

