【问题标题】:How to group and label geom_col in ggplot?如何在ggplot中对geom_col进行分组和标记?
【发布时间】:2019-11-14 04:52:42
【问题描述】:

我正在尝试使用 R 和 ggplot2 从 GraphPad 重现图形。 在少数情况下,我有少量样本的值:

df <- data.frame(Sample = c("blank", "blank", "blank", "A","A","A","A","A","A","B","B","B","B","B", "B", "C","C","C","C","C","C"), 
                 Condition = c("control", "control", "control", "C1", "C1", "C1", "C2", "C2", "C2","C1", "C1", "C1", "C2", "C2", "C2","C1", "C1", "C1", "C2", "C2", "C2"),
                 Value = c(0.719, 1.25, 0.687, 8.19, 4.68, 3.53, 14.1, 7.11, 8.8, 6.48, 7.05, 4.82, 6.32, 4.97, 6.97, 5.5, 7.22, 6.89, 8.89, 6.83, 8.73))

df$Sample <- factor(df$Sample, levels = c("blank", "A", "B", "C")) 
df$Condition <- factor(df$Condition, levels = c("control", "C1", "C2"))

我正在努力将它们组织和绘制为分组(按条件)和标记(按样本),如下所示:

我尝试使用fillposition="dodge",但这完全不是我想要的:

df %>%
  ggplot + 
  aes(x = Sample, y = Value, fill = Condition) + 
  geom_col(position = "dodge")

请注意,我还想从图例中排除空白。

我正在尝试创建、绘制和标记另一列,例如:

df <- df %>%
  mutate(Sample.Condition = paste(Sample, Condition, sep = "."))

..但它变得(太?)复杂了。为了学习,我正在寻找关于如何做到这一点的简单而整洁的解决方案。 谢谢!

【问题讨论】:

  • 是的,创建标签另一列是让 ggplot 做到这一点的方法。你想要的很复杂,而不是 ggplot 想要做的。 ggplot 喜欢将一列映射到 x 轴,并标记该列中的每个唯一值。您没有任何对应于 x 轴上所需的 7 个唯一值的列,因此您需要创建一个。闪避用于分离在单个 x 轴中断内的组,这些组通常在视觉上按颜色或形状分隔,因为它们没有自己的标签。您需要为每个标签添加标签,因此躲避是行不通的。
  • 我看到的唯一其他选项是按条件分面,这将使分组/排序正确,但实际上不在同一个情节上。通过对theme 进行一些调整,您可以使它们看起来非常相似,但这比创建一个新列要多得多。
  • 看起来额外的列仍然是最好的解决方案。谢谢!

标签: r ggplot2 graph


【解决方案1】:

我不知道你是否成功得到你的阴谋,如果你有兴趣,我找到了一种方法:

首先,我计算ValuesValuessd 和@Gregor 的建议,我创建了一个新列,它是@987654330 的串联@和Condition

library(dplyr)
df2 = df%>%
  group_by(Sample,Condition) %>%
  summarise(Mean = mean(Value), Sd = sd(Value)) %>%
  mutate(New_Var = paste0(Sample,Condition))

然后,我们可以绘制数据:

library(ggplot2)
ggplot(df2, aes(x = New_Var, y = Mean, fill = Condition)) +
  geom_bar(stat = "identity", color = "black",position = position_dodge(), width = 0.7) +
  geom_errorbar(aes(ymin = Mean - Sd, ymax = Mean + Sd), width = .2, position = position_dodge(.9)) +
  scale_fill_manual(values = c("black","grey","red"),
                    labels = c("Control","Condition 1", "Condition 2")) +
  scale_x_discrete(limits = c("blankcontrol","AC1","BC1","CC1","AC2","BC2","CC2") , labels = c("Blank","A","B","C","A","B","C")) +
  theme(axis.text.x = element_text(face = "bold",angle = 45),
        legend.title = element_blank()) +
  xlab("") +
  scale_y_continuous(limits = c(0,15), breaks = c(0,5,10,15))

情节看起来与您从 GraphPad 获得的情节非常相似。我同意这不是一件容易的事,但如果你真的想要这个情节,你可以得到它。

编辑 - 在图表上添加单个值

library(dplyr)
dfX= df %>%
  mutate(New_Var2 = paste0(Sample,Condition))
library(ggplot2)
ggplot(df2, aes(x = New_Var, y = Mean, fill = Condition)) +
  geom_bar(stat = "identity", color = "black",position = position_dodge(), width = 0.7) +
  geom_errorbar(aes(ymin = Mean - Sd, ymax = Mean + Sd), width = .2, position = position_dodge(.9)) +
  scale_fill_manual(values = c("black","grey","red"),
                    labels = c("Control","Condition 1", "Condition 2")) +
  scale_x_discrete(limits = c("blankcontrol","AC1","BC1","CC1","AC2","BC2","CC2") , labels = c("Blank","A","B","C","A","B","C")) +
  theme(axis.text.x = element_text(face = "bold",angle = 45),
        legend.title = element_blank()) +
  xlab("") +
  scale_y_continuous(limits = c(0,15), breaks = c(0,5,10,15))+
  geom_jitter(data = dfX, aes(x = New_Var2, y = Value), position=position_jitter(0.3), show.legend = F)

您会得到以下图表:

但是,每个条件只有三个点,我宁愿将均值表示为单个点,并以 sd 作为误差线。类似的东西。

ggplot(df2, aes(x = New_Var, y = Mean, group = Condition)) +
  geom_point(aes(shape = Condition, color= Condition), stat = "identity", position = position_dodge(), size = 2) +
  geom_errorbar(aes(ymin = Mean - Sd, ymax = Mean + Sd, color = Condition), width = .2, position = position_dodge(.9)) +
  scale_shape_manual(values=c(15, 16, 17))+
  scale_color_manual(values = c("black","darkgrey","darkred"), labels = c("Control","Condition 1", "Condition 2")) +
  scale_x_discrete(limits = c("blankcontrol","AC1","BC1","CC1","AC2","BC2","CC2") , labels = c("Blank","A","B","C","A","B","C")) +
  theme(axis.text.x = element_text(face = "bold",angle = 45),
        legend.title = element_blank()) +
  xlab("") +
  scale_y_continuous(limits = c(0,15), breaks = c(0,5,10,15))+
  geom_jitter(data = dfX, aes(x = New_Var2, y = Value, shape = Condition), 
              position=position_jitter(0.3), color = adjustcolor("black",alpha.f = 0.6), 
              show.legend = F, size = 2)

结果图:

但这只是我的个人意见,这取决于你;)

【讨论】:

  • 这确实是一个非常巧妙的解决方案。当我想在上面添加单个点时怎么样(geom_dotplot)?
  • 很高兴您对此表示赞赏。你的意思是每个条形图一分?
  • 对于添加点,您可以通过df2 = data.frame(df2,points = c(5,11,15,9.5,15,10,12))添加一个新列,然后在ggplot的末尾添加geom_point(aes(x=New_Var, y = points))。这应该在每个条形图的顶部添加一个点。是你要找的吗?
  • 好的,我明白了,我将编辑我的答案以在图表中添加值。
  • 不客气 ;) 对于订购条件,您必须使用scale_x_discrete 并以正确的顺序设置limits。如果要“BAC”,可以输入scale_x_discrete(limits = c("blankcontrol","BC1","AC1","CC1","BC2","AC2","CC2") , labels = c("Blank","B","A","C","B","A","C"))。祝您的出版物好运。
【解决方案2】:

最简洁的解决方案可能是引入构面。

df %>%
  ggplot + 
  aes(x = Sample, y = Value, fill = Condition) + 
  geom_col() +
  facet_wrap(~Condition)

【讨论】:

  • 是的,我知道方面,我只是希望有一些更“专用”的解决方案。谢谢:)
猜你喜欢
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
相关资源
最近更新 更多