11

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

由此:

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

有什么建议么?

4

2 回答 2

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,因此它可能会以一些有趣的方式破坏它。但它是,如果没有别的,一个开始。

于 2013-09-18T23:17:55.470 回答
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))

在此处输入图像描述

于 2013-09-19T08:06:16.243 回答