我有时态数据,其中一些时间间隔仅包含缺失值。我想明确地显示那些缺失的值间隔。
目前,我的解决方案是检查值是否为NaN
,如下:
plot file_name using 1:(stringcolumn(num_column) eq "NaN" ? 1/0 : column(num_column)) with lines,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 1000 : 1/0) with points
这将导致y = 1000
的绘图点而不是缺失值的行,这会产生以下结果:
但是,这并不理想,因为a)我需要指定一个y
值来绘制点,而b)它非常难看,特别是当数据集的时间较长时。 / p>
我想生产这样的东西:
也就是说,用一种颜色完全填充这个间隔(可能与我的图像不同,有一些透明度)。请注意,在这些示例中,只有一个缺失值的间隔,实际上在一个图上可以有任意数量。
答案 0 :(得分:3)
一种有点“hacky”的做法是使用两条填充曲线,如下:
plot file_name using 1:(stringcolumn(num_column) eq "NaN" ? 1/0 : column(num_column)) with lines ls 2,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 0 : 1/0) with filledcurve x1 ls 3,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 0 : 1/0) with filledcurve x2 ls 3
两个fillcurve必须具有相同的linestyle,以便我们得到一个统一的矩形。
一个填充曲线有x1
作为参数而另一个x2
,因此一个填充0以上,另一个填充0以下。
您可以在0处删除曲线,并使用以下方法使填充变得透明:
set style fill transparent solid 0.8 noborder
结果如下:
请注意,与其他虚线相比,矩形下方0处的虚线有点不明显。另请注意,如果某些矩形的宽度非常小,它们看起来会比预期的要轻。
答案 1 :(得分:3)
我们可以做一些预处理来实现这一目标。假设我们有以下数据文件 data.txt
1 8
2 6
4 NaN
5 NaN
6 NaN
7 9
8 10
9 NaN
10 NaN
11 6
12 11
以及下面的python 3程序(显然,使用python不是唯一的方法), process.py 1
data = [x.strip().split() for x in open("data.txt","r")]
i = 0
while i<len(data):
if (data[i][1]=="NaN"):
print(data[i-1][0],end=" ") # or use data[i][0]
i+=1
while data[i][1]=="NaN": i+=1
print(data[i][0],end=" ") # or use data[i-1][0]
else: i+=1
这个python程序将读取数据文件,对于每个NaN值范围,它将输出最后一个好的和下一个好的x坐标。在示例数据文件的情况下,它输出2 7 8 11
,它可以用作绘制矩形的边界。现在我们可以在gnuplot 2
breaks = system("process.py")
set for [i=0:words(breaks)/2-1] object (i+1) rectangle from word(breaks,2*i+1),graph 0 to word(breaks,2*i+2),graph 1 fillstyle solid noborder fc rgb "orange"
将在此范围内绘制填充的矩形。它确定了break变量中有多少“块”(两个值的组),然后使用断点作为矩形的左右边界一次读取这两个。
最后,绘制数据
plot "data.txt" u 1:2 with lines
产生
显示NaN值范围内的填充矩形。
为了提供更多的适用性,以下awk程序, process.awk 3 与上面的python程序具有相同的目的,如果awk可用并且python不是:
BEGIN {
started = 0;
last = "";
vals = "";
}
($2=="NaN") {
if (started==0) {
vals = vals " " last;
started = 1;
}
}
($2!="NaN") {
last = $1
if (started==1) {
vals = vals " " last;
started = 0;
}
}
END {
sub(/^ /,"",vals);
print vals;
}
我们可以通过用
替换上面的系统调用来使用它breaks = system("awk -f process.awk data.txt")
<小时/> 1 边界延伸到最后一点和下一点以完全填补空白。如果不需要,则注释值将仅覆盖文件中NaN标识的区域(示例中为4-6和8-10)。程序不会将NaN值作为第一个或最后一个数据点处理。
2 我使用纯橙作为间隙。随意使用任何颜色规格。
3 awk程序以与python程序相同的方式扩展边界,但需要进行更多修改才能获得其他行为。它在处理NaN值时与第一个或最后一个数据点具有相同的限制。