gpt4 book ai didi

r - ggplot boxplot - 对数轴的 mustache 长度

转载 作者:行者123 更新时间:2023-12-03 21:30:02 28 4
gpt4 key购买 nike

我正在尝试使用 ggplot2 创建一个带有对数轴的水平箱线图。但是, mustache 的长度是错误的。

一个最小的可重现示例:

一些数据

library(ggplot2)
library(reshape2)
set.seed(1234)
my.df <- data.frame(a = rnorm(1000,150,50), b = rnorm(1000,500,150))
my.df$a[which(my.df$a < 5)] <- 5
my.df$b[which(my.df$b < 5)] <- 5

如果我使用基数 R 绘制此图 boxplot() , 一切安好
boxplot(my.df, log="x", horizontal=T)

enter image description here

但是有了 ggplot,
my.df.long <- melt(my.df, value.name = "vals")
ggplot(my.df.long, aes(x=variable, y=vals)) +
geom_boxplot() +
scale_y_log10(breaks=c(5,10,20,50,100,200,500,1000), limits=c(5,1000)) +
theme_bw() + coord_flip()

我得到了这个图,其中 mustache 的长度错误(例如,请参阅 mustache 下方有许多额外的异常值而上方没有)。

enter image description here

请注意,没有对数轴,ggplot 的 mustache 长度正确
ggplot(my.df.long, aes(x=variable, y=vals)) +
geom_boxplot() +
theme_bw() + coord_flip()

enter image description here

如何使用具有正确长度 mustache 的 ggplot 生成水平对数箱线图?优选地,晶须延伸至IQR的1.5倍。

注意如解释 here .可以使用 coord_trans(y = "log10")而不是 scale_y_log10 ,这将导致在转换数据之前计算统计数据。然而, coord_trans不能与 coord_flip 一起使用.所以这并不能解决用对数轴创建水平箱线图的问题。

最佳答案

您可以拥有 ggplot使用 boxplot.stats (与 base boxplot 使用的函数相同)来设置盒须和异常值的 y 值。例如:

# Function to use boxplot.stats to set the box-and-whisker locations  
mybxp = function(x) {
bxp = boxplot.stats(x)[["stats"]]
names(bxp) = c("ymin","lower", "middle","upper","ymax")
return(bxp)
}

# Function to use boxplot.stats for the outliers
myout = function(x) {
data.frame(y=boxplot.stats(x)[["out"]])
}

现在我们在 stat_summary 中使用这些函数绘制箱线图,如下例所示:
ggplot(my.df.long, aes(x=variable, y=vals)) +
stat_summary(fun.data=mybxp, geom="boxplot") +
stat_summary(fun.data=myout, geom="point") +
theme_bw() + coord_flip()

现在对于对数变换问题:下图分别显示没有坐标变换, scale_y_log10 , 和 coord_trans(y="log10") .另外,我用过 geom_hline在每个盒须值处添加虚线,并添加了文本以显示实际值。为了减少困惑,我删除了离群点,并且稍微淡化了箱线图,以便其他组件显示得更好。
# Set up common plot elements
p = ggplot(my.df.long, aes(x=variable, y=vals)) +
geom_hline(yintercept=mybxp(my.df$a), colour="red", lty="11", size=0.3) +
geom_hline(yintercept=mybxp(my.df$b), colour="blue", lty="11", size=0.3) +
stat_summary(fun.data=mybxp, geom="boxplot", colour="#000000A0", fatten=0.5) +
#stat_summary(fun.data=myout, geom="point") +
theme_bw() + coord_flip()

br = c(5,10,20,50,100,200,500,1000)

## Create plots

# Without log transformation
p1 = p + scale_y_continuous(breaks=br, limits=c(5,1000)) +
stat_summary(fun.y=mybxp, aes(label=round(..y..)), geom="text", size=3, colour="red") +
ggtitle("No Transformation")

# With scale_y_log10
p2 = p + scale_y_log10(breaks=br, limits=c(5,1000)) + ggtitle("scale_y_log10") +
stat_summary(fun.y=mybxp, aes(label=round(..y..,2)), geom="text", size=3, colour="red") +
stat_summary(fun.y=mybxp, aes(label=round(10^(..y..))), geom="text", size=3,
colour="blue", position=position_nudge(x=0.3))

# With coord_trans
p3 = p + scale_y_continuous(breaks=br, limits=c(5,1000)) +
stat_summary(fun.y=mybxp, aes(label=round(..y..)), geom="text", size=3, colour="red") +
coord_trans(y="log10") + ggtitle("coord_trans(y='log 10')")

三个图如下所示。注意最后一个图,使用 coord_trans没有翻转,因为 coord_trans覆盖 coord_flip .您可能可以使用类似 this SO answer 中的代码的内容。翻转情节,但我还没有在这里做。

第一个没有转换的图显示了正确的值。

第三个图,使用 coord_trans也有一切都在正确的位置。请注意 coord_trans实际上是在不改变绘制点的值的情况下改变绘图的 y 坐标系。正是空间本身被“扭曲”到了对数尺度。

现在,请注意在第二个图中,使用 scale_y_log10 ,盒子在正确的位置,但 mustache 的末端在错误的位置。另一方面,与另外两幅图的比较表明, geom_hline的所有位置s 是正确的。另请注意,与 coord_trans 不同, scale_y_log10获取点本身的日志,并使用未记录的值重新标记 y 轴中断,同时保留绘制点的“空间”不变。您可以通过查看红色文本中的值来看到这一点。蓝色文本中的值是未记录的值。

@dww's answer解释原因 scale_y_log10只会导致 mustache 末端被错误地转换,而框值绘制在正确的位置。

enter image description here

关于r - ggplot boxplot - 对数轴的 mustache 长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38753628/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com