如何用“抖动”生成相同的图,以及如何抖动选定的点(不是所有点)?

时间:2015-09-11 16:07:57

标签: r ggplot2 jitter

我想做的是:

a) ggplot代码生成的图表每次运行时都是相同的[set.seed种类的概念?]和

b)文本标签仅针对具有相同y轴值的标签抖动 - 保留其他文本标签。这似乎是基于点的因子值的某种条件抖动。

以下是一些数据:

dput(df)
structure(list(Firm = c("a verylongname", "b verylongname", "c verylongname", 
"d verylongname", "e verylongname", "f verylongname", "g verylongname", 
"h verylongname", "i verylongname", "j verylongname"), Sum = c(74, 
77, 79, 82, 85, 85, 88, 90, 90, 92)), .Names = c("Firm", "Sum"
), row.names = c(NA, 10L), class = "data.frame")

以下是ggplot代码,使用df:

ggplot(df, aes(x = reorder(Firm, Sum, mean), y = Sum)) +
  geom_text(aes(label = Firm), size = 3, show.guides = FALSE, position = position_jitter(height = .9)) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

请注意,一个版本的图仍然与h和i重叠 - 每次运行上面的代码时,文本标签的位置都会发生变化。

enter image description here

顺便说一句,这个问题conditional jitter稍微改变了x轴上的离散值,但我想在y轴上移动重叠点(仅)。

1 个答案:

答案 0 :(得分:4)

一个选项是添加一列来标记重叠点,然后分别绘制这些点。更好的选择可能是直接移动重叠点的y值,以便我们直接控制它们的位置。我在下面显示了两个选项。

选项1(抖动):首先,添加一列来标记重叠。在这种情况下,因为这些点几乎落在一条线上,所以如果它们的y值太接近,我们可以将任何点标记为重叠。如果检查x值是否也很接近,则可以包含更复杂的条件。

df$overlap = lapply(1:nrow(df), function(i) {
  if(min(abs(df[i, "Sum"] - df$Sum[-i])) <= 1) "Overlap" else "Ignore"
})

在情节中,我把抖动点染成了红色,这样就可以很容易地判断哪些是受影响的。

# Add set.seed() here to make jitter reproducible
ggplot(df, aes(x = reorder(Firm, Sum, mean))) +
  geom_text(data=df[df$overlap=="Overlap",], 
            aes(label = Firm, y = Sum), size = 3,  
            position = position_jitter(width=0, height = 1), colour="red") +
  geom_text(data=df[df$overlap=="Ignore",], 
            aes(label = Firm, y = Sum), size = 3) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

enter image description here

选项2(直接展示位置):另一种选择是直接控制标签的移动量,而不是采取任何jitter发生的事情。在这种情况下,我们知道我们想要使用相同的y值移动每对点。如果我们需要担心x和y值,同一重叠中的两个点以及/或我们需要移动接近但不完全相同的值,则需要更复杂的逻辑。

library(dplyr)

# Create a new column that shifts pairs of points with the same y-value by +/- 0.25
df = df %>% group_by(Sum) %>%
  mutate(SumNoOverlap = if(n()>1) Sum + c(-0.25,0.25) else Sum)

ggplot(df, aes(x = reorder(Firm, Sum, mean), y = SumNoOverlap)) +
  geom_text(aes(label = Firm), size = 3) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

enter image description here

注意:要使抖动可重现,请在抖动的绘图代码之前添加set.seed(153)(或您想要的任何种子值)。