在工作中,我有一组浮点值,我对其进行排序并计算 CDF 并在 gnuplot 中进行绘制。我想画一条线来显示 CDF 的 80% 和 90% 阈值所在的位置,即一条从左侧 @ 0.8 y 刻度线进入的线,接触图形,然后下降到该值可能是什么。这是为了帮助引导观众的眼睛。
数据是自动生成的,我制作了多个绘图,因此我不想每次都手工绘制这些线条。
在 0.8 和 0.9 y 值点处绘制完全穿过绘图的水平箭头很简单,但我不明白如何确定应在何处绘制垂直线。 这是一个关于绘制箭头的问答:Gnuplot: Vertical lines at specific positions ,但位置是先验已知的。
这是一些示例数据(我的工作机器无法访问互联网,因此很难共享)
X Y
5.0 | 0.143
8.0 | 0.288
16.0 | 0.429
25.0 | 0.714
39.0 | 0.857
47.0 | 1.000
有什么想法吗?
最佳答案
这是我的看法(使用百分位数排名),仅假设单变量系列测量可用(您的列标题为 X
)。您可能需要稍微调整它以使用预先计算的累积频率,但这并不困难。
# generate some artificial data
reset
set sample 200
set table 'rnd.dat'
plot invnorm(rand(0))
unset table
# display the CDF
unset key
set yrange [0:1]
perc80=system("cat rnd.dat | sed '1,4d' | awk '{print $2}' | sort -n | \
awk 'BEGIN{i=0} {s[i]=$1; i++;} END{print s[int(NR*0.8-0.5)]}'")
set arrow from perc80,0 to perc80,0.8 nohead lt 2 lw 2
set arrow from graph(0,0),0.8 to perc80,0.8 nohead lt 2 lw 2
plot 'rnd.dat' using 2:(1./200.) smooth cumulative
这会产生以下输出:
当然,您可以根据需要添加任意数量的百分位数;你只需要定义一个新变量,例如perc90
,以及请求另外两个arrow
命令,并替换每一个出现的0.8
(啊......神奇数字的乐趣! )乘以所需的值(在本例中为 0.9)。
对上述代码的一些解释:
- 我生成了一个保存在磁盘上的人工数据集。
- 第 80 个百分位是使用 awk 计算的,但在此之前我们需要
- 删除
table
生成的表头(前四行); (我们可以要求 awk 从第 5 行开始,但我们就这样吧。) - 仅保留第二列;
- 对条目进行排序。
- 删除
- 计算第 80 个百分位的 awk 命令需要截断,这是按照建议完成的 here 。 (在 R 中,我只需使用诸如
trunc(rank(x))/length(x)
之类的函数来获取百分位数排名。)
如果您想尝试一下 R,您可以安全地用对 R 的调用来替换一长串 sed/awk 命令,例如
Rscript -e 'x=read.table("~/rnd.dat")[,2]; sort(x)[trunc(length(x)*.8)]'
假设 rnd.dat 位于您的主目录中。
<小时/>旁注:如果您可以不用 gnuplot,这里有一些 R 命令可以完成此类图形(即使不使用 quantile
函数):
x <- rnorm(200)
xs <- sort(x)
xf <- (1:length(xs))/length(xs)
plot(xs, xf, xlab="X", ylab="Cumulative frequency")
## quick outline of the 80th percentile rank
perc80 <- xs[trunc(length(x)*.8)]
abline(h=.8, v=perc80)
## alternative solution
plot(ecdf(x))
segments(par("usr")[1], .8, perc80, .8)
segments(perc80, par("usr")[3], perc80, .8)
关于r - 如何在 gnuplot 生成的 cdf 上绘制引导线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8985687/