以分类状态作为阶跃函数的 gnuplot 时间序列
gnuplot timeseries with categorical states as step function
我有一个看起来像这样的数据文件:
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 不将字符串识别为分类值。您必须自己完成这些作业 "string → integer"。
进行此映射的最简单方法是使用 awk
等外部工具并即时添加整数值。以下 awk
调用执行此映射并将值添加到输出:
awk -F ';' -v OFS=';' '{
if (!( in array)) {
array[] = length(array)
}
print ,,array[]
}' 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 (!( in array)) { array[] = length(array) }; print ,,array[]}' 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 不是数据处理工具 的结论(虽然该说法通常是正确的!)。
这里应该符合要求:
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)
或</code>return一个fp号码,或者如果他们找不到他们能找到的东西就会出错转换为数字。
<code>=
运算符只比较数值,你必须使用 eq
。
而 a?B:C 是 ternary operator
, returns C 如果 A == 0,否则 B.
我有一个看起来像这样的数据文件:
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 不将字符串识别为分类值。您必须自己完成这些作业 "string → integer"。
进行此映射的最简单方法是使用 awk
等外部工具并即时添加整数值。以下 awk
调用执行此映射并将值添加到输出:
awk -F ';' -v OFS=';' '{
if (!( in array)) {
array[] = length(array)
}
print ,,array[]
}' 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 (!( in array)) { array[] = length(array) }; print ,,array[]}' 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 不是数据处理工具 的结论(虽然该说法通常是正确的!)。
这里应该符合要求:
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)
或</code>return一个fp号码,或者如果他们找不到他们能找到的东西就会出错转换为数字。
<code>=
运算符只比较数值,你必须使用 eq
。
而 a?B:C 是 ternary operator
, returns C 如果 A == 0,否则 B.