R控制抖动功能——避免过度绘制/非随机抖动

R control jitter function - avoid overplotting / non-random jitter

我的问题看起来很简单,我正在使用 ggplot2geom_jitter() 来绘制变量。 (以我的照片为例)

抖动现在会向变量添加一些随机噪声(在此示例中变量仅称为“1”)以防止过度绘制。所以我现在在 y 方向上有随机噪声,很明显,否则会被完全覆盖的部分现在更清晰可见。

但这是我的问题:

如您所见,仍有一些点相互重叠。在我这里的示例中,如果它不是 y 方向上的随机噪声,则可以很容易地避免这种情况……但以某种方式更具战略性地放置偏移量。

我能以某种方式改变 geom_jitter() 行为吗?或者 ggplot2 中是否有类似的功能可以做到这一点?

不是真正的最小示例,但也不会太长:

library("imputeTS")
library("ggplot2")

data <- tsAirgap


# 2.1 Create required data

# Get all indices of the data that comes directly before and after an NA

na_indx_after <- which(is.na(data[1:(length(data) - 1)])) + 1
# starting from index 2 moves all indexes one in front, so no -1 needed for before
na_indx_before <- which(is.na(data[2:length(data)]))

# Get the actual values to the indices and put them in a data frame with a label
before <- data.frame(id = "1", type = "before", input = na_remove(data[na_indx_before]))
after <- data.frame(id = "1", type = "after", input = na_remove(data[na_indx_after]))
all <- data.frame(id = "1", type = "source", input = na_remove(data))

# Get n values for the plot labels
n_before <- length(before$input)
n_all <- length(all$input)
n_after <- length(after$input)



# 2.4 Create dataframe for ggplot2

# join the data together in one dataframe
df <- rbind(before, after, all)


# Create the plot

gg <- ggplot(data = df) +
  geom_jitter(mapping = aes(x = id, y = input, color = type, alpha = type), width = 0.5 , height = 0.5) 

gg <- gg + ggplot2::scale_color_manual(
  values = c("before" = "skyblue1", "after" = "yellowgreen","source" = "gray66"),
)

gg <- gg + ggplot2::scale_alpha_manual(
  values = c("before" = 1, "after" = 1,"source" = 0.3),
)

gg + ggplot2::theme_linedraw() + theme(aspect.ratio = 0.5) + ggplot2::coord_flip()

这么多好的建议...以下是 Bens 对我的示例的建议:

我将部分代码更改为:

gg <- ggplot(data = df, aes(x = input,  color = type, fill = type, alpha = type)) +
  geom_dotplot(binwidth = 15) 

对我来说基本上也能正常工作。 Jon 建议的 ggbeeplot 对我的目的也很有效。

我想到了一个我非常喜欢的 hack,使用 ggrepel。它通常用于标签,但没有什么可以阻止您将标签变成一个点。

df <- data.frame(x = rnorm(200),
                 col = sample(LETTERS[1:3], 200, replace = TRUE),
                 y = 1)

ggplot(df, aes(x, y, label = "●", color = col)) + # using unicode black circle
  ggrepel::geom_text_repel(segment.color = NA, 
                           box.padding = 0.01, key_glyph = "point")

此方法的一个缺点是 ggrepel 可能需要大量时间来处理大量点,并且每次更改绘图大小时都会以不同方式重新计算。一种更快的替代方法是使用 ggbeeswarm::geom_quasirandom,它使用确定性过程来定义看起来随机的抖动。

ggplot(df, aes(x,y, color = col)) +
  ggbeeswarm::geom_quasirandom(groupOnX = FALSE)