【问题标题】:gnuplot timeseries with categorical states as step function以分类状态作为阶跃函数的 gnuplot 时间序列
【发布时间】:2015-08-30 23:15:54
【问题描述】:

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

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 可以实现这种情节吗?如果,那你会怎么做?

【问题讨论】:

  • 您有已知的州数量吗?您知道州名吗?还是这是动态的?
  • 我有不同的文件包含不同的状态。大多数情况下,这些是二进制“开/关”或“活动/非活动”。最好有一个通用的解决方案,因为名称取决于加载的文件,并且有些文件具有更多状态。

标签: gnuplot time-series categorical-data


【解决方案1】:

不,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

输出是

或者,如果您无法访问awk,您也可以使用例如一个python脚本,如下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)

并调用它

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

旁注:也许也可以仅使用 gnuplot 来执行此操作,但这可能会变得非常丑陋,请参阅 Gnuplot, plotting a graph with text on y axis 了解类似的用例。

【讨论】:

  • 感谢您的回答。 gnuplot 不提供此功能是否有(历史)原因。这似乎是数据探索的一项重要任务?
  • 主要原因是gnuplot不想成为一个功能齐全的数据处理工具。它的主要重点是绘制数据,而不是处理它们。所以这种任务外包给其他工具,比较合适。这也是gnuplot没有数组数据结构的原因。
  • 听起来很合理,并且符合 unix 哲学。感谢您指出这一点。
【解决方案2】:

由于只有两种状态,我不会说这符合 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。 而a?B:C 是ternary operator,如果A == 0,则返回C,否则返回B。

【讨论】:

  • 在 cmets @jdog 中说,可以出现两个以上的状态,这导致我引用了您的评论。这些状态可能因文件而异。
猜你喜欢
  • 2020-03-14
  • 2021-04-12
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 2015-11-12
  • 2021-10-08
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多