I have count data from several sample
s, which map to two class
es, two group
s, and three type
s:
library(dplyr)
set.seed(1)
df <- data.frame(type = c(rep("A",12), rep("B",12), rep("C",12)),
group = rep(c("O1","O1","O2","O2","O3","O3","Y1","Y1","Y2","Y2","Y3","Y3"),3),
class = rep(c("c1","c2"),18),
sample = rep(c("O1.c1_1","O1.c2_1","O2.c1_1","O2.c2_1","O3.c1_1","O3.c2_1",
"Y1.c1_1","Y1.c2_1","Y2.c1_1","Y2.c2_1","Y3.c1_1","Y3.c2_1"),3),
n = round(runif(36,10,50))) %>%
dplyr::group_by(type) %>% dplyr::mutate(type.n = sum(n)) %>%
dplyr::ungroup() %>% dplyr::mutate(f = n/type.n)
df$sample <- factor(df$sample, levels = c("O1.c1_1","O1.c2_1","O2.c1_1","O2.c2_1","O3.c1_1","O3.c2_1","Y1.c1_1","Y1.c2_1","Y2.c1_1","Y2.c2_1","Y3.c1_1","Y3.c2_1"))
df$class <- factor(df$class, levels = c("c1","c2"))
Each sample
encodes in its name the class
and group
it was sampled from (for example, these might be single-cell RNA-seq samples, where class
corresponds to a tissue, group
corresponds to an animal, and type
corresponds to a cell type).
I'd like to plot the sample
s' df$f
values as a stacked bar plot, where each bar is type
, color-coded by group
, and pattern-coded by class
, and I'd like to manually specify both the group
(bar sector) colors as well as the pattern colors.
Here's a data.frame
for that:
colors.df <- data.frame(group = levels(df$group),color = c("#55a189","#d27551","#7585a9","#ffa5ea","#c7ff64","#ffff38"))
I'm trying ggpattern
for that using this code:
library(ggplot2)
library(ggpattern)
ggplot(df, aes(type,f, fill = group))+
geom_bar_pattern(colour="black", position = "stack", stat = "identity", mapping = aes(pattern = class), linewidth = 0.15, pattern = "circle", pattern_density = 0.2, pattern_spacing = 0.01, pattern_angle = 120) +
scale_pattern_fill_manual(values = c(c1= 'black', c2 = 'white'))+
scale_pattern_color_manual(values = c(c1= 'black', c2 = 'white'))+
scale_fill_manual(values = colors.df$color)+
theme_minimal()
But unfortunately it does not color-code the patterns as I'm trying to specify in my command.
Any idea?
that I would like to plot using R
ggplot2
as a stacked bar plot, where each bar is a
You have a few issues.
Firstly, your mapping of the pattern
aesthetic to class
is over-ridden by setting pattern = "circle"
later in the call to geom_bar_pattern
. If you just want different colored circles as the pattern fill, you will need to specify a scale_pattern_manual
with values = c("circle", "circle"))
.
Secondly, to keep the bar segments in the correct order, you will need to use group = interaction(class, group)
as part of the mapping.
Thirdly, your scale_
calls aren't doing anything because pattern_fill
and pattern_color
are separate aesthetics that you haven't mapped yet.
Finally, you have some redundancy. geom_bar(stat = "identity")
was superseded by geom_col
several years ago, and position = "stack"
is already the default.
Fixing all this, we have:
library(ggplot2)
library(ggpattern)
ggplot(df, aes(type,f, fill = group)) +
geom_col_pattern(aes(pattern = class, group = interaction(class, group),
pattern_fill = class, pattern_color = class),
linewidth = 0.15, pattern_density = 0.2,
pattern_spacing = 0.01, pattern_angle = 120) +
scale_pattern_fill_manual(values = c(c1 = 'black', c2 = 'white')) +
scale_pattern_color_manual(values = c(c1 = 'black', c2 = 'white')) +
scale_pattern_manual(values = c("circle", "circle")) +
scale_fill_manual(values = colors.df$color) +
theme_minimal(16)