在多图中,当我得到一个子图的错误all points Y value undefined
时,如何使gnuplot继续并至少输出其余的子图? / strong>
我们假设以下示例来自某些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
我想将该数据与其他来源的其他时间值数据,其他采样时间一起绘制在多图中,但使用相同的X范围。 出于演示目的,我们简单地使用:
# data for second sub-plot
y(x) = sin(x)
我可以使用以下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
结果: multiplot with full X range
很明显,群集周围的分辨率分别为50,-160和120。因此,我想将X范围分解为多个10分钟的缩放片段。使用自动缩放,将缩放Y轴以提供更好的分辨率。我希望获得5个图,大致覆盖上图中标记为1-5的区域。
我正在使用do for
循环来生成缩放图:
# 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
}
细分1仍可按预期生产: multiplot zoomed to first 10 minutes
但是当到达第2段(X范围为00:10至00:20)和更高的第4段(00:30至00:40)时,出现错误all points Y value undefined
,并且gnuplot退出。请注意,段2失败是因为数据集中根本没有任何点,但是段4失败了,因为strip_zero()
将现有点转换为NaN。
我正在寻找一种在发生错误后继续前进的方法,以便生成所有5个多图,并且仍然至少绘制每个多图中的第二个子图。
我不在乎gnuplot的输出是什么,而不是失败的子图(什么都没有,空白图空间,空网格,给定X范围之外的点之间的连接线,.. )。
我希望不需要使用shell脚本等进行外部预处理的解决方案,以确保最大的可移植性。
本机Windows 10或cygwin下的Gnuplot 5.2补丁程序级别5。
答案 0 :(得分:0)
要跳过多图环境中的图,通常可以使用set 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
这将导致: