堆栈指向一个在另一个之上

时间:2013-09-12 21:30:39

标签: r plot ggplot2

为了防止过度绘图,我想要一种替代抖动的方法,只需将点一个堆叠在另一个上面的平均值(通过给定量的增量垂直偏移它们而不是像抖动那样添加随机值)。

由此:

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)

我想要的是这样的:

example image

这应该可以通过stat_bindot()进行。

有什么建议吗?

2 个答案:

答案 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))

enter image description here

你也可以在水平方向轻推

ggplot(example, aes(x, y)) +
  geom_point(aes(group=interaction(x,y)), size=5, 
             position=position_nudge(width=0.03))

enter image description here

您必须将组交互指定为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))

enter image description here

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)

enter image description here

# 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))

enter image description here