27

我的数据如下所示:

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 的“线点”图,以及代表 ($2,$3) 的每个组合的 8 条不同的线,例如:(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 预处理我的所有数据文件(通过将它们分成单独的文件,然后可以在同一个图中绘制),但这并不理想......

谢谢!

4

2 回答 2

14

+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'

注意“< awk ...”。Gnuplot 打开一个 shell,运行命令,然后从管道中读回结果。不需要临时文件。当然,在这个例子中,我们可以有{print $1,$4}(而不是{print $0})并把 using 规范放在一起,例如:

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 不好玩吗?

于 2012-06-25T16:07:16.893 回答
4

...只是偶然发现了这个老问题...好吧,当您想要绘制连接的过滤数据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 中的结果:

在此处输入图像描述

于 2019-02-01T08:28:44.113 回答