按两个标准填充ggplot2直方图

Fill ggplot2 histogram by two criteria

我有一些数据 (x) 我想绘制成直方图。有两种样本类型 (s),每个样本以两种不同的方式收集 (r)。

我想将它们绘制为由 sr 填充的堆叠直方图——最好的方法是按照我的最后一个例子对它们进行分面,但是我是space限定的

我可以使用单个 geom_histogram 绘制由 s 填充的数据。我可以绘制两个 geom_histogram 来绘制不同的 r。我不知道如何让不同的 geoms 堆叠起来。我还没有想出如何填充它们,但 ggnewscale 可能是一个选项。

我想选择填充,例如(例如)s == 红色、蓝色和 r == 相应 s 颜色的浅色、深色。

有什么建议吗?

library(tidyverse)
library(tibble)

x <-           c(0,0,0,0,0,1,1,1,1,-1,-1,-1,-1,2,2,2,-2,-2,-2,3,3,-3,-3,4,-4, 8,8,8,8,8,9,9,9,9,9,7,7,7,10,10,10,6,6,6,11,11,5,5,12,4)
r <- as.factor(c(1,2,2,2,1,1,2,2,2, 1, 1, 2, 2,2,2,2, 1, 1, 2,2,2, 2, 2,2, 2, 1,1,2,2,2,1,1,1,2,1,1,2,2, 1, 2, 2,2,2,2, 2, 1,1,2, 1,1))
s <- c(rep.int("a", 25), rep.int("b", 25))

figsd <- tibble(x,r,s)
  
figsd %>% 
ggplot(aes(x=x)) +
  geom_histogram(aes(fill = s), binwidth = 1, position = "stack") +
  coord_cartesian(ylim = c(0,5))



figsd %>% 
  ggplot(aes(x=x)) +
  geom_histogram(data = . %>% filter(r == 1), aes(fill = s), binwidth = 1,alpha = 0.5, position = "stack") +
  geom_histogram(data = . %>% filter(r != 1), aes(fill = s), binwidth = 1,alpha = 0.5, position = "stack") +
  coord_cartesian(ylim = c(0,5))



figsd %>% 
  ggplot(aes(x=x)) +
  geom_histogram(aes(fill = r), binwidth = 1,position = "stack") +
  coord_cartesian(ylim = c(0,5)) +
  facet_grid(s ~ .)

reprex package (v0.3.0)

于 2020 年 11 月 2 日创建

您可以在两个分组之间创建交互并将其传递给 fill 审美:

library(ggplot2)

figsd <- data.frame(
    x = c(0,0,0,0,0,1,1,1,1,-1,-1,-1,-1,2,2,2,-2,-2,-2,3,3,-3,-3,4,-4, 8,8,8,8,8,9,9,9,9,9,7,7,7,10,10,10,6,6,6,11,11,5,5,12,4),
    r = as.factor(c(1,2,2,2,1,1,2,2,2, 1, 1, 2, 2,2,2,2, 1, 1, 2,2,2, 2, 2,2, 2, 1,1,2,2,2,1,1,1,2,1,1,2,2, 1, 2, 2,2,2,2, 2, 1,1,2, 1,1)),
    s = c(rep.int("a", 25), rep.int("b", 25))
)


ggplot(figsd, aes(x, fill = interaction(r, s))) +
    geom_histogram(binwidth = 1) + 
    scale_fill_manual(values = c(
        '1.a' = 'lightblue', 
        '1.b' = 'darkblue', 
        '2.a' = 'pink', 
        '2.b' = 'darkred'
    )) + 
    labs(fill = 'group')

此处的级别本身没有任何意义,因此您可能需要特意设置填充颜色以显示关系。

另请注意,无论出于何种原因,interaction() 的扩展性都不是很好——如果您处理 10 万行,paste() 会快得多,即使 interaction() 更多就您要显示的内容而言在语义上是正确的。

摘自@alistaire 的评论。

重新排序和着色以使其更好一些。

library(tidyverse)
library(tibble)

x <-           c(0,0,0,0,0,1,1,1,1,-1,-1,-1,-1,2,2,2,-2,-2,-2,3,3,-3,-3,4,-4, 8,8,8,8,8,9,9,9,9,9,7,7,7,10,10,10,6,6,6,11,11,5,5,12,4)
r <- as.factor(c(1,2,2,2,1,1,2,2,2, 1, 1, 2, 2,2,2,2, 1, 1, 2,2,2, 2, 2,2, 2, 1,1,2,2,2,1,1,1,2,1,1,2,2, 1, 2, 2,2,2,2, 2, 1,1,2, 1,1))
s <- c(rep.int("a", 25), rep.int("b", 25))

figsd <- tibble(x,r,s)

figsd %>%  mutate(r = factor(r, levels=c(2, 1))) %>% 
ggplot(aes(x=x)) +
  geom_histogram(aes(fill = interaction(r,s)), binwidth = 1, position = "stack")+ 
  scale_fill_manual(breaks = c("1.a","2.a","1.b","2.b"),
                    values = c('1.a' = 'lightblue', '1.b' = 'pink', '2.a' = 'darkblue', '2.b' = 'darkred'),
                    labels = c("1.a","2.a","1.b","2.b")
                   ) +
  coord_cartesian(ylim = c(0,5))

reprex package (v0.3.0)

创建于 2020-11-02