gnuplot时间序列,分类状态为步进函数

时间:2015-08-26 13:44:14

标签: gnuplot time-series categorical-data

我有一个看起来像这样的数据文件:

0;State a
1;State a
2;State b
3:State b
4:State a

第一列表示以秒为单位的时间,第二列表示某种状态。

我想在gnuplot中随时间绘制事件的出现。我正在尝试使用以下内容进行绘图:

set datafile separator ";"
plot 'data' using 1:2:yticlabels(2)

但是我收到以下错误:

warning: Skipping data file with no valid points
                                       ^
x range is invalid

似乎gnuplot不会将字符串识别为分类值。结果应该看起来像一个非连续的阶梯函数:

       ^
State b┼       ┌───────┐
       │       │       │
State a┼───────┘       └────
       │
       ┼───┼───┼───┼───┼───┼─>
       0   1   2   3   4   5           

这种情节可以用gnuplot吗?如果,你会怎么做?

2 个答案:

答案 0 :(得分:2)

不,gnuplot不会将字符串识别为分类值。你必须做那些作业"字符串→整数"自己。

执行此映射的最简单方法是使用awk之类的外部工具,并即时添加整数值。以下awk调用执行此映射并将值添加到输出:

awk -F ';' -v OFS=';' '{
  if (!($2 in array)) { 
    array[$2] = length(array)
  }
  print $1,$2,array[$2]
}' data.csv

使用gnuplot语法

plot "< awk ..."

您可以直接将awk电话与绘图结合起来:

set datafile separator ";"
set offset 0.1,0.1,0.1,0.1
set xtics 0,1
plot "< awk -F ';' -v OFS=';' '{if (!($2 in array)) { array[$2] = length(array) }; print $1,$2,array[$2]}' data.csv" using 1:3:ytic(2) w step lw 3 notitle

输出

enter image description here

或者,如果您无法访问awk,则也可以使用例如cat.py进行预处理。像以下from __future__ import print_function import sys a={} with open(sys.argv[1], 'r') as f: for line in f: fields = line.strip().split(';') if (not fields[1] in a): a[fields[1]] = len(a) print("{0};{1};{2}".format(fields[0], fields[1], a[fields[1]]), file=sys.stdout) 一样的python脚本:

plot "< python cat.py data.csv" ...

并用

调用它
quantity_traded < 20000

旁注:也许也可以使用gnuplot来做这件事,但这可能会变得非常难看,请参阅Gnuplot, plotting a graph with text on y axis了解类似的用例。

答案 1 :(得分:0)

由于只有两种状态,我不认为这符合 gnuplot不是数据处理工具判决(虽然该语句通常是正确的!)。

这应符合条例草案:

f(s) = s eq "state a" ? 0 : s eq "state b" ? 1 : NaN
set dataf sep ";"
plot dataf using 1:(f(stringcolumn(2))) with steps # or fsteps

如果你有十几个不同的状态,那就是另一个故事。

说明:您需要stringcolumn()函数,因为column(2)$2会返回一个fp编号,如果他们找不到可以转换为数字的错误,则会出错。 =运算符仅比较数值,您必须使用eq。 并且?B:C是ternary operator,如果A == 0则返回C,否则返回B.