为了防止过度绘图,我想要一种替代抖动的方法,它只是将一个点堆叠在另一个点上(以给定数量的增量垂直偏移它们,而不是像抖动那样添加随机值)。
由此:
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()
。
有什么建议么?
没有一个内置位置能做到这一点,而且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
,因此它可能会以一些有趣的方式破坏它。但它是,如果没有别的,一个开始。
远非@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))