为了防止过度绘图,我想要一种替代抖动的方法,只需将点一个堆叠在另一个上面的平均值(通过给定量的增量垂直偏移它们而不是像抖动那样添加随机值)。
由此:
example <- data.frame(x=c(1,1,1,2,2,2,2), y=c(1,1,1,2,2,2,2))
qplot(data=example,x=x, y=y)
我想要的是这样的:
这应该可以通过stat_bindot()
进行。
有什么建议吗?
答案 0 :(得分:10)
内置位置都没有这么做,geom_dotplot
也不是很正确,因为它只适用于一个维度。我拼凑了一个新的职位,做了正确的事情,但需要手动调整以使一切正常。
library("proto")
PositionNudge <- proto(ggplot2:::Position, {
objname <- "nudge"
adjust <- function(., data) {
trans_x <- function(x) {
lx <- length(x)
if (lx > 1) {
x + .$width*(seq_len(lx) - ((lx+1)/2))
} else {
x
}
}
trans_y <- function(y) {
ly <- length(y)
if (ly > 1) {
y + .$height*(seq_len(ly) - ((ly+1)/2))
} else {
y
}
}
ddply(data, .(group), transform_position, trans_x=trans_x, trans_y=trans_y)
}
})
position_nudge <- function(width = 0, height = 0) {
PositionNudge$new(width = width, height = height)
}
我称它为轻推,因为我已经采取了其他的东西(堆叠,躲闪)
使用它
ggplot(example, aes(x, y)) +
geom_point(aes(group=interaction(x,y)), size=5,
position=position_nudge(height=0.03))
你也可以在水平方向轻推
ggplot(example, aes(x, y)) +
geom_point(aes(group=interaction(x,y)), size=5,
position=position_nudge(width=0.03))
您必须将组交互指定为geom_point
的审美,并且需要传递给position_nudge
的确切宽度/高度取决于点的大小和输出的大小。例如,对于4x6输出,您需要
ggplot(example, aes(x, y)) +
geom_point(aes(group=interaction(x,y)), size=10,
position=position_nudge(height=0.13))
0.13的值只是试验和错误,直到看起来正确。从geom_dotplot
中学到的一些代码和东西可能会在这里重复使用,以使其更加健壮。此外,我没有使用除example
之外的任何数据对此进行测试,因此它可能会以一些有趣的方式打破它。但是,如果没有别的,那就是一个开始。
答案 1 :(得分:5)
远不是@Brian Diggs很好的答案的复杂性,而是一个快速的选择,我在geom_dotplot
创建的对象中使用'闪避数据'来生成新的y值。需要一些手动推文才能使'闪避'缩放正确。
# create ggplot object with geom_dotplot
g1 <- ggplot(example, aes(x = x, y = y)) +
geom_dotplot(stackdir = "center")
# grab dodge values from plot object
dodge <- ggplot_build(g1)[["data"]][[1]]$stackpos
# create new y values that are adjusted by 'dodge'
example$y2 <- example$y + dodge * 0.05
# plot using new y values
ggplot(example, aes(x = x, y = y2)) +
geom_point(size = 5)
# seems to work decently on grouped data as well
df2 <- rbind(example, example)
df2$grp <- rep(c("a", "b"), each = 7)
df2
g2 <- ggplot(df2, aes(x = x, y = y, colour = grp)) +
geom_dotplot(stackdir = "center", stackgroups = FALSE)
dodge <- ggplot_build(g2)[["data"]][[1]]$stackpos
df2$y2 <- df2$y + dodge * 0.04
ggplot(df2, aes(x = x, y = y2, colour = grp)) +
geom_point(size = 5, position = position_dodge(width = 0.05))