我不明白
zsort
的以下行为(检查help zsort
)。
如果我有一个数据集,第二列包含 NaN
,第一列包含 zsort
,为什么 gnuplot 不按预期方式对其进行排序,即按第一列和第二列中的原始值排序?
脚本:(需要 gnuplot>=5.4)
### unexpected behavior of zsort
reset session
$Data <<EOD
4 14.0
6 16.0
3 13.0
5 NaN
2 12.0
7 17.0
8 NaN
1 11.0
9 NaN
EOD
set table $Test
plot $Data u 1:2:1 smooth zsort
unset table
print $Test
### end of script
结果:
# Curve 0 of 1, 8 points
# Curve title: "$Data u 1:2:1"
# x y type
3 13 i
4 14 i
6 16 i
5 NaN u
2 12 i
7 17 i
8 NaN u
1 11 i
显然,当第二列包含
NaN
并且子块单独排序时,数据块会被分成子块。最后的第 9 NaN u
行被抑制。
预期结果:
# Curve 0 of 1, 8 points
# Curve title: "$Data u 1:2:1"
# x y type
1 11 i
2 12 i
3 13 i
4 14 i
5 NaN u
6 16 i
7 17 i
8 NaN u
9 NaN u
有没有办法得到这个预期的结果?
这是一个真正麻烦的解决方法。基本思想是:
NaN
替换为肯定超出 y 范围的数字 yOut
,以避免与真实数据发生冲突smooth zsort
到桌子上yOut
替换回 NaN
尝试通过 与
NaN
比较和/或在 smooth zsort
内一起缩短任务并未成功(到目前为止)。所以,我必须进行字符串比较。希望有更好的解决方案。
实际上,使用
valid(2)
可以稍微缩短脚本(检查 help valid
)。
脚本:(适用于 gnuplot>=5.4.0)
### workaround for zsort with NaN in data
reset session
$Data <<EOD
4 14.0
6 16.0
3 13.0
5 NaN
2 12.0
7 17.0
9 NaN
1 11.0
8 NaN
EOD
stats $Data u (abs($2)) nooutput
yOut = 1.01*STATS_max + 1 # get a number which is surely out of range
set table $Temp
plot $Data u 1:(valid(2) ? $2 : yOut):1 smooth zsort
set table $Test
plot $Temp u 1:($2==yOut ? NaN : $2) w table
unset table
print $Test
### end of script
结果:
1 11
2 12
3 13
4 14
5 nan
6 16
7 17
8 nan
9 nan
您严重误用了 zsort,它的目的是非常不同的。话虽如此,我认为下面的变体可能足够接近您所要求的,您可以使用它。它将原始第 2 列移动到第 3 列(版本 5.4)或第 4 列(版本 6),但无论您接下来要对排序后的数据执行什么操作,都应该能够在那里找到它。
$Data <<EOD
4 14.0
6 16.0
3 13.0
5 NaN
2 12.0
7 17.0
8 NaN
1 11.0
9 NaN
EOD
set table $Test
plot $Data u 1:1:1:2 smooth zsort with points lc variable
unset table
print $Test
# Curve 0 of 1, 9 points
# Curve title: "$Data u 1:1:1:2"
# x y color type
1 1 11 i
2 2 12 i
3 3 13 i
4 4 14 i
5 5 NaN i
6 6 16 i
7 7 17 i
8 8 NaN i
9 9 NaN i
如果您退一步并解释您实际上想要做什么,也许有一个更好的答案,根本不涉及 zsort。