Graphics 如何使用GNUPlot根据列中的值绘制单行/多行

Graphics 如何使用GNUPlot根据列中的值绘制单行/多行,graphics,plot,gnuplot,multiple-columns,Graphics,Plot,Gnuplot,Multiple Columns,我在使用gnuplot时有点问题。这是我的数据文件: From Time Packets Jitter 127.0.0.1:53091 1 0 274 127.0.0.1:53091 2 0 417 127.0.0.1:53091 3 36 53 127.0.0.1:53091 4 215 55 127.0.0.1:53090 4 215 55 127.0.0.1:53091 5 215 33 127.0.0.1:53090 6 256 78 (我为测试输入了“时间

我在使用gnuplot时有点问题。这是我的数据文件:

From Time Packets Jitter  
127.0.0.1:53091 1 0 274  
127.0.0.1:53091 2 0 417  
127.0.0.1:53091 3 36 53  
127.0.0.1:53091 4 215 55  
127.0.0.1:53090 4 215 55  
127.0.0.1:53091 5 215 33  
127.0.0.1:53090 6 256 78
(我为测试输入了“时间”,但在它工作后,它将被datetime替换)

我想画两个不同的图形,x轴上都有
Time
列,y轴上有
Packets
列(第一个图形上)和Jitter列(第二个图形上)。但是,正如您可能已经看到的,我不知道我将拥有多少不同于
from
列的值(最小值为1,但我不知道最大值,数据文件将刷新,一些值将每x秒添加一次)。
因此,我的问题是,我想在两个图形上分别创建另一个“行”,每个“行”与值不同。
事实上,在行标题中有
From
值(例如:“127.0.0.1:53091”)。
如果可以更改列顺序,我想补充一点

我试过:

plot 'data.log' using 3:xtic(2) title 'Packets' with lines, \
     'data.log' using 4:xtic(2) title 'Jitter' with lines
但是它在同一个图形上(我还没有使用multiplot,我以前试过让multiplot行工作)

可能吗?如果是,如何在gnuplot中绘制这两个图形?

如果没有,我们可以删除
Jitter
图形,并仅在单个图形上绘制
数据包
列,但与值不同

我不确定我是否理解您的问题,但至少我可以回答
如何在gnuplot中绘制这两个图形?

set multiplot layout 1,2
plot 'data.log' using 3:xtic(2) title 'Packets' with lines
plot 'data.log' using 4:xtic(2) title 'Jitter' with lines
unset multiplot
将产生以下结果:


这是一个依赖于多种标准工具的解决方案,这些工具应该可以在任何标准Linux机器上使用,并且主要基于bash。让我们从您提供的数据文件开始,不带第一行

步骤1:将数据拆分为每个字段1的一个文件:
awk-f split.awk
,在
split.awk
中包含以下内容:

#!/usr/bin/awk -f
# erase previous files
BEGIN { system("rm file_*.dat"); }

# print each line in a specific file
 { print $0 >>( "file_" $1 ".dat") }
步骤2:复制每个生成的数据文件的第一行(因为在gnuplot中使用其中一个字段作为标题会在打印时忽略该行):

步骤3:生成一个gnuplot脚本,该脚本包含一个打印不同文件的
plot
命令(请参见下面的完整脚本)

FIY,最后一个“0”绘图之所以存在,是因为要将多个文件打印到一个绘图上,gnuplot需要在行尾添加一个反斜杠。如果有一个,并且在下一行没有要绘制的内容,则会生成一个错误。所以我只能找到这个愚蠢的把戏来让它发挥作用

步骤4:调用生成的gnuplot脚本

有了您提供的数据,下面的脚本将结束为:

也许可以缩短一些,但我喜欢保持可读性

完整脚本:

#!/bin/bash

# 1 - split data into one file per field 1
awk -f split.awk < data.log

# 2 - duplicate first line (useful for gnuplot)
for f in `ls file_*.dat`; do 
    head -n 1 $f > tmp.dat
    cat $f >> tmp.dat
    mv tmp.dat $f
done;

# 3 - generate gnuplot script
echo "set terminal pngcairo size 800,500" > plot.plt
echo "set output 'b.png'" >> plot.plt
echo "set multiplot layout 1,2" >> plot.plt

echo "set title 'Packets'" >> plot.plt
echo "plot \\" >> plot.plt
for f in `ls file_*.dat`; do 
    echo "   '$f' using 2:3 title columnheader(1) with linespoints lw 2, \\" >> plot.plt
done;
echo "    0 notitle" >> plot.plt

echo "set title 'Jitter'" >> plot.plt
echo "plot \\" >> plot.plt
for f in `ls file_*.dat`; do 
    echo "   '$f' using 2:4 title columnheader(1) with linespoints lw 2, \\" >> plot.plt
done;
echo "    0 notitle" >> plot.plt

echo "unset multiplot" >> plot.plt

# 4 - call gnuplot script
gnuplot plot.plt
#/bin/bash
#1-将每个字段的数据拆分为一个文件1
awk-f split.awktmp.dat
类别$f>>tmp.dat
mv tmp.dat$f
完成;
#3-生成gnuplot脚本
echo“设置端子pngcairo尺寸800500”>plot.plt
echo“设置输出'b.png'”>>plot.plt
echo“设置多点布局1,2”>>plot.plt
回显“设置标题‘数据包’”>>plot.plt
echo“plot\\”>>plot.plt
对于'ls file.*.dat'中的f;做
回显“$f”,使用2:3标题列标题(1)和线条点lw 2,\\”>>plot.plt
完成;
echo“0 notitle”>>plot.plt
echo“设置标题‘抖动’”>>plot.plt
echo“plot\\”>>plot.plt
对于'ls file.*.dat'中的f;做
回显“$f”,使用2:4标题列标题(1)和行点lw 2,\\”>>plot.plt
完成;
echo“0 notitle”>>plot.plt
echo“unset multiplot”>>plot.plt
#4-调用gnuplot脚本
gnuplot plot.plt

这里有一个解决方案,它不需要外部文件。首先,我提取第一列中的所有不同源,并将它们存储在gnuplot变量中:

filename = 'data.log'
from=system('tail -n +2 '.filename. '| cut -f 1 -d " " | sort | uniq')
对于打印期间的过滤,我使用
awk
并定义一个gnuplot函数

select_source(w) = sprintf('< awk ''{if ($1 == "%s") print }'' %s', w, filename)

首先,感谢您的回复。这就是我想要做的,但是,正如您在我的“示例”数据中看到的,可能有不同的IP和不同的端口,但我不知道可以有多少不同的IP:port(在我的示例中有两个不同的IP:port:127.0.0.1:53091和127.0.0.1:53090)。所以我的目标是,每当这个字段中有另一个值时,在每个图形上画另一条线。是不是更清楚了?对不起,如果没有的话,我明白了。问题确实在于,绘图上的每一行都必须对应于
plot
命令(或绘图命令中的“序列”)。所以我认为这需要一些数据预处理来分离不同的地址,然后为每个地址生成一个plot命令。不是那么容易,但我会考虑一下,可能是一些
awk
处理。如果你想感谢我,你可以投票给我答案…;-)哦,还有一个问题:只有两个端口号?或者其他几个?因为我上面的评论考虑了可能还有其他几个的假设。如果只有两个,那么会更简单。不,可能有一个或多个(两个,三个,我不知道数字)不同的IP:Port(IP和Port可以更改)。在multiplot上,与第一列没有差异(例如,x轴上有两个4值,但IP:端口不同)。所以是的,也许是awk处理。谢谢你花时间解决我的问题。我必须添加一些东西:我的目标是每x秒回复一次这个图形,并且可以在两个循环之间添加或删除不同的IP:Port值。(我的名声在15岁以下,所以我不能投票:()等待你的帮助,我使用了这个命令:<代码>字符串命令,非常感谢你的帮助,它对我的工作可能非常有用。我会尝试用C++编写这个脚本,但是用POPUN命令可能会很容易。另外,谢谢你花时间来解决我的问题。哦,谢谢你的回应。现在我有CHO了。ICE来选择哪个脚本对我的使用更有效(并且把这个脚本放在C++中也很容易)。
filename = 'data.log'
from=system('tail -n +2 '.filename. '| cut -f 1 -d " " | sort | uniq')
select_source(w) = sprintf('< awk ''{if ($1 == "%s") print }'' %s', w, filename)
filename = 'data.log'
from=system('tail -n +2 '.filename. '| cut -f 1 -d " " | sort | uniq')
select_source(w) = sprintf('< awk ''{if ($1 == "%s") print }'' %s', w, filename)

set style data linespoints
set multiplot layout 1,2

set title 'Packets'
plot for [f in from] select_source(f) using 2:3 title f

set title 'Jitter'
plot for [f in from] select_source(f) using 2:4 title f

unset multiplot