Gnuplot 尽管';所有点Y值未定义';一个子图中的错误

Gnuplot 尽管';所有点Y值未定义';一个子图中的错误,gnuplot,Gnuplot,在多点打印中,当我得到一个子图的错误所有点Y值未定义时,如何使gnuplot继续并至少输出剩余的子图? 背景: 让我们假设以下来自某个GPS跟踪器的时间纬度数据示例。事实上,我的数据包含超过10万个亚秒的样本,跨越多天 $DATA << EOD # Zero values are invalid (no GPS fix) and shall be ignored. # # Segment 1) Trip 1 around longitude 50.0: 00:01 49.9999

在多点打印中,当我得到一个子图的错误
所有点Y值未定义时
,如何使gnuplot继续并至少输出剩余的子图?

背景: 让我们假设以下来自某个GPS跟踪器的时间纬度数据示例。事实上,我的数据包含超过10万个亚秒的样本,跨越多天

$DATA << EOD
# Zero values are invalid (no GPS fix) and shall be ignored.
#
# Segment 1) Trip 1 around longitude 50.0:
00:01   49.99990
00:02   49.99994
00:03   50.00006
00:04   50.00008
00:05   0
00:06   0
00:07   0
00:08   50.00004
00:09   50.00002
#
# Segment 2) no data recorded at all
# ...
#
# Segment 3) Trip 2 around longitude -164.0:
00:21   -163.99992
00:22   -163.99998
00:23   -164.00006
00:24   -164.00004
00:25   0
00:26   0
00:27   0
00:28   -164.00002
00:29   -164.00002
#
# Segment 3) only invalid data recorded
00:31   0
00:32   0
00:33   0
00:34   0
00:35   0
00:36   0
00:37   0
00:38   0
00:39   0
#
# Segment 4) Trip 3 around longitude 120.0:
00:41   120.00000
00:42   120.00002
00:43   119.99998
00:44   119.99996
00:45   119.99994
00:46   119.99998
00:47   120.00002
00:48   120.00006
00:49   120.00002
EOD
我可以使用以下gnuplot代码绘制完整的时间范围(00:00到00:50):

# General settings
timeformat = "%H:%M"
set xdata time
set timefmt timeformat
set xtics timedate
set xtics format timeformat
set xtics 10*60
set mxtics 10
set ytics format "%.5f"

# Function to skip zero / invalid longitude values:
strip_zero(Y) = ( Y == 0 ? NaN : Y )

# Plot full X range:
set multiplot layout 2, 1
set xrange [0 : 50*60]
set yrange [-180<*:*<180]
plot $DATA using 1: (strip_zero($2)) with lines notitle, \
     $DATA using 1: (strip_zero($2)) with points notitle
set yrange [*:*]
plot y(x) with lines
unset multiplot
第1部分仍然可以按预期生产:

但是当点击第2段(X范围00:10到00:20)和之后的第4段(00:30到00:40)时,我得到错误
所有点Y值未定义
,并且gnuplot退出。请注意,段2失败是因为数据集中根本没有点,但段4失败是因为现有点通过
strip\u zero()
转换为NaN

我正在寻找一种方法来跟踪错误,以便生成所有5个多点图,并且至少每个多点图中的第二个子图仍然被绘制

我不关心gnuplot输出的是什么,而不关心失败的子图(没有,一个空白的图表空间,一个空的网格,给定X范围之外的点之间的连接线,…)

  • 将for循环移出gnuplot并移入一些shell脚本可能只适用于一个(子)图,但不能解决在multiplot中跳过更多子图的问题
  • 更改子图的顺序(以便在gnuplot退出之前绘制无问题的子图)不是一个选项,因为所有子图数据主要受相同问题的影响
我更喜欢不需要外部预处理的shell脚本等解决方案,以确保最大的可移植性


本机Windows 10或cygwin下的Gnuplot 5.2 patchlevel 5

在多点打印环境中跳过打印通常可以通过
设置multiplot next
来完成,但是,如果跳过没有数据的打印,我不知道是否有“简单”的方法来实现。那么,看看下面的解决方法。 它是未优化的代码,但在gnuplot 5.2.5中进行了测试。 基本思想是将数据绘制到一个虚拟表中,并检查时间是否在段的范围内,以及是否包含除
0
以外的一些数据。 可能还有很多工作要做才能使图表看起来漂亮。把它看作一个可能的起点

### skipping plot having no data
reset session

$DATA << EOD
# Zero values are invalid (no GPS fix) and shall be ignored.
#
# Segment 1) Trip 1 around longitude 50.0:
00:01   49.99990
00:02   49.99994
00:03   50.00006
00:04   50.00008
00:05   0
00:06   0
00:07   0
00:08   50.00004
00:09   50.00002
#
# Segment 2) no data recorded at all
# ...
#
# Segment 3) Trip 2 around longitude -164.0:
00:21   -163.99992
00:22   -163.99998
00:23   -164.00006
00:24   -164.00004
00:25   0
00:26   0
00:27   0
00:28   -164.00002
00:29   -164.00002
#
# Segment 3) only invalid data recorded
00:31   0
00:32   0
00:33   0
00:34   0
00:35   0
00:36   0
00:37   0
00:38   0
00:39   0
#
# Segment 4) Trip 3 around longitude 120.0:
00:41   120.00000
00:42   120.00002
00:43   119.99998
00:44   119.99996
00:45   119.99994
00:46   119.99998
00:47   120.00002
00:48   120.00006
00:49   120.00002
EOD

# data for second sub-plot
y(x) = sin(x)

# General settings
timeformat = "%H:%M"
set xdata time
set timefmt timeformat
set xtics timedate
set xtics format timeformat
set xtics 10*60
set mxtics 10
set ytics format "%.5f"

# Function to skip zero / invalid longitude values:
strip_zero(Y) = ( Y == 0 ? NaN : Y )


# Plot 10-minute slices:
set multiplot layout 2,5 columnsfirst
set margins 8,1,2,1

x_start = 0
x_end = 40
x_step = 10
do for [i = x_start*60:x_end*60:x_step*60] {
    set xrange [i : i + x_step*60]
    ContainsData = 0
    set table $Dummy
        plot $DATA using 1:\
        ((timecolumn(1)>=i) && (timecolumn(1)<=(i + x_step*60)) && ($2!=0) ?\
        ContainsData=1 : 0) with table
    unset table

    if (ContainsData == 0) { set multiplot next }
    else {
        plot [i : i + x_step*60] $DATA using 1:(strip_zero($2)) with lp pt 7 lc rgb "red" notitle
    }
    plot y(x) with lines notitle
}
unset multiplot
### end of code
###跳过没有数据的绘图
重置会话
$DATA=i)和&(时间列(1)
# Plot 10-minute slices:
do for [x_min = 0 : 40 : 10] {
    set multiplot layout 2, 1
    set xrange [x_min * 60 : (x_min + 10) * 60]
    set yrange [-180<*:*<180]
    plot $DATA using 1: (strip_zero($2)) with lines notitle, \
         $DATA using 1: (strip_zero($2)) with point notitle
    set yrange [*:*]
    plot y(x) with lines
    unset multiplot
}
### skipping plot having no data
reset session

$DATA << EOD
# Zero values are invalid (no GPS fix) and shall be ignored.
#
# Segment 1) Trip 1 around longitude 50.0:
00:01   49.99990
00:02   49.99994
00:03   50.00006
00:04   50.00008
00:05   0
00:06   0
00:07   0
00:08   50.00004
00:09   50.00002
#
# Segment 2) no data recorded at all
# ...
#
# Segment 3) Trip 2 around longitude -164.0:
00:21   -163.99992
00:22   -163.99998
00:23   -164.00006
00:24   -164.00004
00:25   0
00:26   0
00:27   0
00:28   -164.00002
00:29   -164.00002
#
# Segment 3) only invalid data recorded
00:31   0
00:32   0
00:33   0
00:34   0
00:35   0
00:36   0
00:37   0
00:38   0
00:39   0
#
# Segment 4) Trip 3 around longitude 120.0:
00:41   120.00000
00:42   120.00002
00:43   119.99998
00:44   119.99996
00:45   119.99994
00:46   119.99998
00:47   120.00002
00:48   120.00006
00:49   120.00002
EOD

# data for second sub-plot
y(x) = sin(x)

# General settings
timeformat = "%H:%M"
set xdata time
set timefmt timeformat
set xtics timedate
set xtics format timeformat
set xtics 10*60
set mxtics 10
set ytics format "%.5f"

# Function to skip zero / invalid longitude values:
strip_zero(Y) = ( Y == 0 ? NaN : Y )


# Plot 10-minute slices:
set multiplot layout 2,5 columnsfirst
set margins 8,1,2,1

x_start = 0
x_end = 40
x_step = 10
do for [i = x_start*60:x_end*60:x_step*60] {
    set xrange [i : i + x_step*60]
    ContainsData = 0
    set table $Dummy
        plot $DATA using 1:\
        ((timecolumn(1)>=i) && (timecolumn(1)<=(i + x_step*60)) && ($2!=0) ?\
        ContainsData=1 : 0) with table
    unset table

    if (ContainsData == 0) { set multiplot next }
    else {
        plot [i : i + x_step*60] $DATA using 1:(strip_zero($2)) with lp pt 7 lc rgb "red" notitle
    }
    plot y(x) with lines notitle
}
unset multiplot
### end of code