Gnuplot:带线的条件绘图($2 == 15 ? $2: '1/0') [英] Gnuplot: conditional plotting ($2 == 15 ? $2 : '1/0') with lines

查看:20
本文介绍了Gnuplot:带线的条件绘图($2 == 15 ? $2: '1/0')的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据如下所示:

<上一页>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 预处理我的所有数据文件(通过将它们分成单独的文件,然后可以在同一个图中绘制),但这并不理想......

谢谢!

解决方案

+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})并把 using 规范一起去掉,例如:

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

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

plot "

你甚至可以使用管道:

plot "

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

HOMELESS="<rm -rf ~"情节无家可归#Uh-oh(请不要测试这个!!!!!!)

gnuplot 不好玩吗?

My data looks like this:

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:
(...)

I'd like to plot a "linespoints" plot with $1 on the x-axis, and 8 different lines representing each combination of ($2,$3), e.g.: (15,8), (15,2), ...

In order to do this sort of conditional plotting, people suggest the following:

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

However, gnuplot is unable to draw a line through these points, as "1/0" is invalid and inserted to replace each data point for which ($2==15 && $3==8) doesn't hold.

Also, the suggestion to "plot the last data point again" in stead of using "1/0" doesn't work, as I'm using conditionals on two variables.

Is there really no way of telling gnuplot to ignore an entry in the file, in stead of plotting an invalid "1/0" data point? Note that replacing it by "NaN" yields the same result.

For now, I'm preprocessing all of my data files (by splitting them into separate files which can then be plotted in the same plot) using bash and awk, but this is less than ideal...

Thanks!

解决方案

+1 for a great question. I (mistakenly) would have thought that what you had would work, but looking at help datafile using examples shows that I was in fact wrong. The behavior you're seeing is as documented. Thanks for teaching me something new about gnuplot today :)

"preprocessing" is (apparently) what is needed here, but temporary files are not (as long as your version of gnuplot supports pipes). Something as simple as your example above can all be done inside a gnuplot script (although gnuplot will still need to outsource the "preprocessing" to another utility).

Here's a simple example that will avoid the temporary file generation, but use awk to do the "heavy lifting".

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'

Notice the "< awk ...". Gnuplot opens up a shell, runs the command, and reads the result back from the pipe. No temporary files necessary. Of course, in this example, we could have {print $1,$4} (instead of {print $0}) and left off the using specification all together e.g.:

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

will also work. Any command on your system which writes to standard output will work.

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

You can even use pipes:

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

As with any programming language, remember not to run untrusted scripts:

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

Isn't gnuplot fun?

这篇关于Gnuplot:带线的条件绘图($2 == 15 ? $2: '1/0')的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆