使用Gnuplot对缺失值进行着色间隔

时间:2016-02-23 15:25:10

标签: gnuplot

我有时态数据,其中一些时间间隔仅包含缺失值。我想明确地显示那些缺失的值间隔。

目前,我的解决方案是检查值是否为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的绘图点而不是缺失值的行,这会产生以下结果:

enter image description here

但是,这并不理想,因为a)我需要指定一个y值来绘制点,而b)它非常难看,特别是当数据集的时间较长时。 / p>

我想生产这样的东西:

enter image description here

也就是说,用一种颜色完全填充这个间隔(可能与我的图像不同,有一些透明度)。请注意,在这些示例中,只有一个缺失值的间隔,实际上在一个图上可以有任意数量。

2 个答案:

答案 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

结果如下:

enter image description here

请注意,与其他虚线相比,矩形下方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

产生

enter image description here

显示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值时与第一个或最后一个数据点具有相同的限制。