2

I am trying to create a panel of grouped stacked bar graphs, but the legend is not appearing automatically for the "age" below. How can I add this legend explicitly?

library(ggplot2)

# create the dataset
species=c(rep("A" , 2) , rep("B" , 2))
strain=rep(c("i" , "ii" ),2)
age=rep(c(1,2,3,4),4)
count=abs(rnorm(16 , 0 , 15))
data=data.frame(species,strain,age,count)

ggplot(data,aes(x=strain,y=count,fill=age))+
  geom_bar(stat = "identity",size=0.5,col="black",fill=rep(c("black","saddlebrown","darkgreen","goldenrod"),times=4))+
  facet_wrap(~species)+
  labs(x="Species",y="Count")

2 Answers2

1

Because you specify fill=rep(c("black","saddlebrown","darkgreen","goldenrod"),times=4) inside geom_bar() after aes(fill = age). You should use scale_fill_xxx to manually specify the desired colors.

library(dplyr)
library(ggplot2)

# create the dataset
set.seed(123)
species <- c(rep("A", 2), rep("B", 2))
strain <- rep(c("i", "ii"), 2)
age <- c(rep(c(1, 3, 4, 2), 1), rep(c(2, 4, 2, 3), 2), rep(c(3, 1, 3, 1), 1))
count <- abs(rnorm(16, 0, 15))
data <- data.frame(species, strain, age, count)

### convert age to factor
data <- data %>% 
  as_tibble() %>% 
  mutate(age = factor(age)) %>% 
  arrange(species, strain)
data
#> # A tibble: 16 x 4
#>    species strain age   count
#>    <fct>   <fct>  <fct> <dbl>
#>  1 A       i      1      8.41
#>  2 A       i      2      1.94
#>  3 A       i      2     10.3 
#>  4 A       i      3      6.01
#>  5 A       ii     3      3.45
#>  6 A       ii     4     25.7 
#>  7 A       ii     4      6.68
#>  8 A       ii     1      1.66
#>  9 B       i      4     23.4 
#> 10 B       i      2      6.91
#> 11 B       i      2     18.4 
#> 12 B       i      3      8.34
#> 13 B       ii     2      1.06
#> 14 B       ii     3     19.0 
#> 15 B       ii     3      5.40
#> 16 B       ii     1     26.8

ggplot(data, aes(x = strain, y = count, fill = age)) +
  geom_col(color = 'black') +
  facet_grid(~ species) +
  scale_fill_brewer(palette = 'Dark2') +
  labs(x = "Species", y = "Count") +
  theme_minimal(base_size = 14)

### user-defined color scheme
myColor <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c')
ggplot(data, aes(x = strain, y = count, fill = age)) +
  geom_col(color = 'black') +
  facet_grid(~ species) +
  scale_fill_manual(values = myColor) +
  labs(x = "Species", y = "Count") +
  theme_minimal(base_size = 14)

Created on 2018-10-09 by the reprex package (v0.2.1.9000)

Tung
  • 26,371
  • 7
  • 91
  • 115
  • Thanks, but I realize I should have indicated that age is actually categorical and not continuous. Thus, I would like the four bars in each stack to have different colours, but the same for all stacks. See [link] (https://i.stack.imgur.com/fRJyQ.jpg) but it doesn't have the legend. – user3574652 Oct 10 '18 at 01:55
  • Gotta go now but check this out https://stackoverflow.com/questions/52032323/r-how-to-make-single-stacked-bar-chart-in-ggplot2/52032491#52032491 – Tung Oct 10 '18 at 02:42
  • See my updated answer. I change `age` variable to have more variation so that we can see the stacked bars – Tung Oct 10 '18 at 03:34
0

OK, I think I've got it with your help @Tung:

ggplot(data,aes(x=strain,y=count,fill=age))+
  geom_col() +
  geom_bar(stat = "identity",size=0.5,col="black",fill=rep(c("black","saddlebrown","darkgreen","goldenrod"),times=4))+
  facet_wrap(~species)+
  labs(x="Species",y="Count")+
  theme(legend.position = "right") +
  theme(axis.title.y = element_text(margin = margin(r = 20)))+
  scale_fill_manual(values = c("black","saddlebrown","darkgreen","goldenrod"))

enter image description here

  • You should remove `,fill=rep(c("black","saddlebrown","darkgreen","goldenrod"),times=4)` on the 3rd line as it's not needed – Tung Oct 10 '18 at 03:32
  • Also you don't need both `geom_col()` & `geom_bar()`. FYI, `geom_col()` = `geom_bar(stat = 'identity')` – Tung Oct 10 '18 at 03:35
  • Thanks @Tung. However, removing the geom_col() resulted in the legend not appearing again, and taking out the "fill..." on the 3rd line reversed the order of the age stack (top-to-bottom: 1, 2, 3, 4). In my case I would prefer it top-to-bottom: 4, 3, 2, 1. – user3574652 Oct 10 '18 at 13:47
  • P.S. I couldn't understand why you were getting the same colours on two blocks of the same stack, but I now notice that where you define "age" is different than mine. – user3574652 Oct 10 '18 at 13:53
  • If you want to control the order of the stacked bar, take a look at `factor` e.g. https://stackoverflow.com/questions/42710056/reverse-stacked-bar-order – Tung Oct 11 '18 at 05:41