如何根据GNUPlot中列的值绘制单行/多行 [英] How to plot single/multiple lines depending on values in a column with GNUPlot
问题描述
使用gnuplot有一点问题。这是我的数据文件:
来自时间数据包抖动
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
time用于测试,但它会在工作后用日期时间替换)
我想绘制两个不同的图形,其中 Time
列中的x轴和数据包
列(在第一个图形上)&抖动列(在第二个图形上)在y轴上。但是,正如你可能已经看到的,我不知道从 From
列中有多少不同的值(最小值为1,但我不知道最大值,数据文件将被刷新,并且每个x秒都会添加一些值)。
所以我的问题是我想让另一个'line'不同于 From $ c两个图形上的$ c>值。
实际上,在行标题中使用 From
值(例如:127.0.0.1:53091) 。
我想补充一点,如果可以更改列顺序。
我试过了:
plot'data.log'using 3 :xtic(2)title'带有行的数据包',\
'data.log'使用4:xtic(2)title'Jitter'with lines
但它在同一图形上(我没有使用多槽,我试图让多行代码在之前工作)。
有可能吗?如果是这样,我该如何在gnuplot中绘制这两个图形?
如果没有,我们可以移除 Jitter
图形,并且只绘制 Packets
列,但使用不同的 From
值。
这是一个依赖几个标准工具的解决方案,应该可以在任何标准Linux机器上使用,而且大多数基于bash。让我们从您提供的数据文件开始,没有第一行。
第1步:将数据拆分为一个文件每场1: awk -f split.awk< data.log
,其中 split.awk
:
#!/ usr / bin / awk -f
第2步:复制每个生成的数据文件的第一行(因为在gnuplot中使用其中一个字段作为标题会忽略该行当绘制时):
#擦除前面的文件
BEGIN {system(rm file _ *。dat); }
#打印特定文件中的每一行
{print $ 0>>(file_$ 1.dat)}
for f in`ls file _ *。dat`;做
头-n 1 $ f> tmp.dat
cat $ f>> tmp.dat
mv tmp.dat $ f
完成;
第3步:生成一个gnuplot脚本,该脚本包含<$ c $
echoplot
绘制不同文件的命令(参见下面的完整脚本)。 \\>>在`ls file _ *。dat`中为plot.plt
for f;做
使用2:3标题栏标题(1)回显'$ f',并带有线点lw 2,\\>> plot.plt
完成;
echo0 notitle>> plot.plt
FIY,最后的0图仅仅是因为将几个文件绘制到单个绘图,gnuplot在行尾需要一个尾部反斜杠。如果有一个,并且在下面一行没有任何内容,则会生成一个错误。所以我只能找到这个愚蠢的技巧才能使它工作...
第4步:调用生成的gnuplot脚本。
使用您提供的数据,以下脚本最终为:
可能本来可以缩短,但我喜欢保持可读性。
完整脚本:
#!/ bin / bash
#1 - 将数据拆分为一个文件每场1
awk -f split.awk< data.log
#2 - 复制第一行(对gnuplot有用)
用于`ls file _ *。dat`中的f;做
头-n 1 $ f> tmp.dat
cat $ f>> tmp.dat
mv tmp.dat $ f
完成;
#3 - 生成gnuplot脚本
echoset terminal pngcairo size 800,500> plot.plt
echoset output'b.png'>> plot.plt
echoset multiplot layout 1,2>> plot.plt
echoset title'Packets'>> plot.plt
echoplot \\>>在`ls file _ *。dat`中为plot.plt
for f;做
使用2:3标题栏标题(1)回显'$ f',并带有线点lw 2,\\>> plot.plt
完成;
echo0 notitle>> plot.plt
echoset title'Jitter'>> plot.plt
echoplot \\>>在`ls file _ *。dat`中为plot.plt
for f;做
使用2:4标题栏标题(1)回应'$ f',并带有线点lw 2,\\>> plot.plt
完成;
echo0 notitle>> plot.plt
echounset multiplot>> plot.plt
#4 - 调用gnuplot脚本
gnuplot plot.plt
I have a little problem using gnuplot. Here is my datafile:
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
(I put that "time" for the test, but it will be replaced by a datetime after it works)
I want to draw two different graphics, with
Time
column in x axis on both, andPackets
column (on a first graphic) & Jitter column (on a second graphic) in y axis. But, as you may have seen, I don't know how many different values from theFrom
column I will have (minimum 1, but I don't know the maximum, the data file will be refresh and some values will be added each x seconds).
So my problem is that I want to make another 'line' each differentFrom
values on both graphics.
In fact, having theFrom
value in title of lines (example : "127.0.0.1:53091").
I want to add that if it's possible to change column order.I tried:
plot 'data.log' using 3:xtic(2) title 'Packets' with lines, \ 'data.log' using 4:xtic(2) title 'Jitter' with lines
But it's on the same graphic (I don't use multiplot yet, I tried to make the multiple lines works before).
Is it possible ? If it is, How can I plot this two graphics in gnuplot ?
If not, we can remove theJitter
graphic, and plot only thePackets
column on a single graphic but with the differentFrom
values.解决方案Here is a solution relying on several standard tools that should be available on any standard Linux box, and mostly based on bash. Lets starts with the datafile you provide, without the first line.
Step 1: split data into one file per field 1 :
awk -f split.awk < data.log
, with the following insplit.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") }
Step 2: duplicate first line of each produced datafile (because using one of the fields as title in gnuplot makes this line ignored when plotting):
for f in `ls file_*.dat`; do head -n 1 $f > tmp.dat cat $f >> tmp.dat mv tmp.dat $f done;
Step 3: generate a gnuplot script that holds a
plot
command that plots the different files (see full script below).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
FIY, the last "0" plot is there only because to plot several files onto a single plot, gnuplot needs a trailing backslash at the end of the line. And if there is one, and nothing to plot at the following line, an error is generated. So I could only find this dumb trick to make it work...
Step 4: call the generated gnuplot script.
With the data you provided, the script below ends up as:
Probably could have been shorter, but I like to keep things readable.
Full script:
#!/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
这篇关于如何根据GNUPlot中列的值绘制单行/多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!