如何使用2个csv文件使用GNUPlot绘制填充曲线图

时间:2016-05-06 02:45:58

标签: gnuplot

如果我有2个csv文件(" CSV1.csv" dataname_1和" CSV2.csv" dataname_2),我该如何绘制填充曲线图来自2个csv文件的数据。这些CSV文件的格式相同,其中2是时间戳,5是值using 2:5

我正在尝试这个:

plot dataname_2 using 2:5 title "Above" with filledcurves above lc rgb 'blue',\
     dataname_1 using 2:5 title "Below" with filledcurves below lc rgb 'red',\
     dataname_2 using 2:5 title "Engine Starts" with lines lc rgb "#1E90FF",\
     dataname_1 using 2:5 title "Engine Hours" with lines lc rgb "#FF1493" 

我需要修改上面的代码,以便输出:

enter image description here

1 个答案:

答案 0 :(得分:2)

一个可能始终有效的解决方案是使用gnuplot可以处理和绘制数据的方式使用任何外部工具准备数据。我知道gnuplot的理念是专注于绘图,而不必专注于绘图的数据准备。但是,最好具有最少的功能集来进行一些基本的数据准备。

在您的情况下,您有几个问题,好吧,我们称之为挑战;-)

  • with filledcurves需要同一文件或数据块中的数据
  • 但是,gnuplot无法轻松地逐行合并数据文件(可以采取一些解决方法,请参见:https://stackoverflow.com/a/61559658/7295599)。 gnuplot只需添加即可。
  • 后者对您没有帮助,因为with filledcurves的上下曲线需要相同的x,即x,y1,y2,并且您的数据具有x1,y1x2,y2
  • 但是,gnuplot无法轻松地对数据重新采样(可以通过一些解决方法,请参见:Resampling data with gnuplot
  • with filledcurves不能直接用非单调递增的x填充曲线(数据不是这种情况。这里仅出于说明目的)(可以通过一些解决方法来查看:https://stackoverflow.com/a/53769446/7295599或{{3} })

所有这些的解决方法如下(适用于gnuplot 5.2,也许可以进行调整以使用早期版本):

假设:

  1. 两个文件或数据块中的数据x1,y1x2,y2
  2. 数据不一定具有相同的x,即x1,y1x2,y2
  3. 数据可能包含非单调的x
  4. 两条曲线只有一个 交点(嗯,下面的解决方法将只取第一个)

过程:

  1. (如果还没有的话)将数据放入数据块中。

  2. 找到曲线的交点。

  3. 创建新的数据块:Filled1从起点到交点使用Data1,从交点到起点向后使用Data2。 Filled2使用Data1从端点向后到交点,并使用Data2从交点到端点。

  4. 绘制$Data1$Data2 with lines$Filled1$Filled2 with filledcurves

除非有专门的功能,否则在另一种编程语言中,步骤2和3可能不会很短。

将文件获取到数据块:(另请参见此处https://stackoverflow.com/a/56176717/7295599

# get files to datablocks
set table $Data1
    plot 'myFile1.dat' u 1:2 w table
set table $Data2
    plot 'myFile2.dat' u 1:2 w table
unset table`

代码 :(复制并粘贴gnuplot> = 5.2)

### fill intersecting curves from two files not having identical x
reset session

$Data1 <<EOD
1   1
2   0
4   1
3   3
5   5
6   6
8   8
9   9
EOD

$Data2 <<EOD
1    3
3.5  5
7.5  1
9    7
EOD

# orientation of 3 points a,b,c: -1=clockwise, +1=counterclockwise
Orientation(a,b,c) = sgn((word(b,1)-word(a,1))*(word(c,2)-word(a,2)) - \
                         (word(c,1)-word(a,1))*(word(b,2)-word(a,2)))

# check for intersection of segment a-b with segment c-d,
# 0=no intersection, 1=intersection
IntersectionCheck(a,b,c,d) = \
    Orientation(a,c,b) == Orientation(a,d,b) || \
    Orientation(c,a,d) == Orientation(c,b,d) ? 0 : 1

# coordinate of intersection
M(a,b) = real(word(a,1)*word(b,2) - word(a,2)*word(b,1))

N(a,b,c,d) = (word(a,1)-word(b,1))*(word(c,2)-word(d,2)) - \
             (word(a,2)-word(b,2))*(word(c,1)-word(d,1))

Px(a,b,c,d) = (M(a,b)*(word(c,1)-word(d,1)) - (word(a,1)-word(b,1))*M(c,d))/N(a,b,c,d)
Py(a,b,c,d) = (M(a,b)*(word(c,2)-word(d,2)) - (word(a,2)-word(b,2))*M(c,d))/N(a,b,c,d)

Intersection(a,b,c,d) = sprintf("%g %g", Px(a,b,c,d), Py(a,b,c,d))

stop = 0
do for [i=1:|$Data1|-1] {
    a = $Data1[i]
    b = $Data1[i+1]
    do for [j=1:|$Data2|-1] {
        c = $Data2[j]
        d = $Data2[j+1]
        if (IntersectionCheck(a,b,c,d)) { 
        i0 = i; j0 = j
        stop=1; break }
    }
    if (stop) { break }
}

# create the datablocks for the outline to be filled
set print $Filled1
    do for [k=1:i0] { print $Data1[k] }
    print Intersection(a,b,c,d)
    do for [k=j0:1:-1] { print $Data2[k] }
set print $Filled2
    do for [k=|$Data1|:i0+1:-1] { print $Data1[k] }
    print Intersection(a,b,c,d)
    do for [k=j0+1:|$Data2|] { print $Data2[k] }
set print

set key top left
plot $Filled1 u 1:2 w filledcurves lc rgb 0x3f48cc, \
     $Filled2 u 1:2 w filledcurves lc rgb 0xed1c24, \
     $Data1 u 1:2 w lp pt 7 lw 5 lc rgb 0x99d9ea, \
     $Data2 u 1:2 w lp pt 7 lw 5 lc rgb 0xff80c0
### end of code

结果:

gnuplot: load datafile 1:1 into datablock