如何在Gnuplot中使用子字符串

4

我想使用一列中的子字符串来绘制数据文件。我的数据文件以以下格式包含数据:

1 (15, 3): dX: -1.619, dY: 3.315, dXSc: 0.981, dYSc: 0.993
2 ( 4,16): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977
...

我希望您能将括号中的数字(x,y)作为y轴和x轴进行绘制,类似于以下示例:

plot "data.dat" u substr(($2),7,8 ):substr(($2),10,11)

这个应该怎么写才是正确的语法呢?
2个回答

5

使用gnuplot正确地执行这个任务有一点棘手,因为gnuplot不允许指定任意格式的输入。通常,最好的方法是使用外部工具提取数据,然后将生成的文件输入到gnuplot中(也可以使用语法(plot '< script data.dat'...)直接进行处理)。

但是,在您的情况下,有一个小技巧可以让gnuplot正常工作,具体步骤如下:

  • Use set datafile separator ':' to have the information of both x and y in a single column.
  • Use strstrt to determine the start and end string positions of the x and y values.

    For the x-value this would be

    substr(s, strstrt(s, "(")+1, strstrt(s, ",")-1)
    
  • Add 0.0 to the resulting substrings to have them implicitely converted to real values.

一个完整的脚本,可以与您的示例数据一起使用,如下:

set datafile separator ":"
get_x(c) = 0.0 + substr(strcol(c), strstrt(strcol(c), "(") + 1, strstrt(strcol(c), ",") - 1)
get_y(c) = 0.0 + substr(strcol(c), strstrt(strcol(c), ",") + 1, strstrt(strcol(c), ")") - 1)

plot 'data.dat' using (get_x(1)):(get_y(1)) with points pt 7 ps 2

感谢您的帮助,不幸的是我收到了错误信息: “内部错误:对非字符串类型应用子字符串范围运算符”我的数据文件看起来像这样: 1 (15, 3): dX: -1.619, dY: 3.315, dXSc: 0.981, dYSc: 0.993 2 ( 4,16): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977 ...我想将括号中的数字(x,y)作为y绘制在x上,使用以下命令:plot "data.dat" using (substr(strcol(2),2,3)):(substr(strcol(2),5,6))造成错误的原因是什么?谢谢 - collin Mcdavids
终于找到时间尝试了一下,真是太神奇了:它能正常工作。非常感谢!我在哪里可以找到关于像get_(x)这样的命令的信息?问候。 - collin Mcdavids
太好了 :) 将这些函数粘合在一起需要更详细的了解 gnuplot 的数据处理。Gnuplot 通常不是执行此类解析的正确工具,尽管在像您这样的某些情况下可以完成。在许多情况下,最好使用外部脚本,例如 Python 或任何其他语言,来执行实际的解析并将生成的数据传递给 gnuplot,例如 plot '< python script.py data.dat' - Christoph

0

仅供记录:对于gnuplot 4.6,Christoph的答案肯定是一个不错的选择。

然而,在OP提问时,gnuplot 5.0.0已经发布。 gnuplot 5.0.0(2015年1月)具有定义多个数据文件分隔符的选项,请查看help datafile separator。有了这个,任务就简化为:

脚本:

### extract numbers between various separators
reset session

$Data <<EOD
1 (15, 3): dX: -1.619, dY: 3.315, dXSc: 0.981, dYSc: 0.993
2 ( 4,16): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977
3 ( 1.5,10.5): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977
EOD

set datafile separator "(,)"

plot $Data u 2:3 w lp pt 7 lc "red"
### end of script

结果:

enter image description here

添加:

实际上,你也可以设置四个分隔符,即"(,):",并将你的表格拆分后写入一个新的“干净”表格$DataNew中。你必须小心选择哪些列,在这里选择的是1:2:3:6:8:10:12

脚本:

### extract numbers between various separators, get "clean" table
reset session

$Data <<EOD
1 (15, 3): dX: -1.619, dY: 3.315, dXSc: 0.981, dYSc: 0.993
2 ( 4,16): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977
3 ( 1.5,10.5): dX: -0.540, dY: -0.540, dXSc: 0.992, dYSc: 0.977
EOD

set datafile separator "(,):"
set table $DataNew
    plot $Data u 1:2:3:6:8:10:12 w table
unset table
set datafile separator    # set to default

print $DataNew
# plot whatever you like...
### end of script

结果:

$DataNew

 1       15      3       -1.619   3.315  0.981   0.993
 2       4       16      -0.54   -0.54   0.992   0.977
 3       1.5     10.5    -0.54   -0.54   0.992   0.977

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接