Barplot becoming stacked when I try to map custom colours to each group in ggplot2

71 Views Asked by At

I want to produce a horizontal grouped barplot using ggplot2. Data are grouped by Name, each Name has one Color and two School, which should be visualized with different transparencies (Alpha). I have put all the data I need into my data frame (test).

library(tidyverse)

test <- structure(list(Name = c("Jean", "Jean", "Mike", "Mike", "Ruth", 
                                "Ruth", "Elia", "Elia", "Jess", "Jess"), 
                       School = c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B"), 
                       Value = c(11L, 8L, 15L, 16L, 27L, 22L, 0L, 4L, 0L, 3L), 
                       Color = c("#E55C30FF", "#E55C30FF","#FBB91FFF", "#FBB91FFF", "#FCFFA4FF", "#FCFFA4FF", "#C7E8AC", "#C7E8AC", "#228B22", "#228B22"),
                       Alpha = c(0.9, 0.4, 0.9, 0.4,0.9, 0.4, 0.9, 0.4, 0.9, 0.4)), 
                  row.names = c(NA, -10L), class = "data.frame")

test

   Name School Value     Color Alpha
1  Jean      A    11 #E55C30FF   0.9
2  Jean      B     8 #E55C30FF   0.4
3  Mike      A    15 #FBB91FFF   0.9
4  Mike      B    16 #FBB91FFF   0.4
5  Ruth      A    27 #FCFFA4FF   0.9
6  Ruth      B    22 #FCFFA4FF   0.4
7  Elia      A     0   #C7E8AC   0.9
8  Elia      B     4   #C7E8AC   0.4
9  Jess      A     0   #228B22   0.9
10 Jess      B     3   #228B22   0.4

I am struggling with mapping the right color to each group. This is my code so far, which achieves the grouping, the plot being horizontal, the transparency, and the grey contouring. But I cannot map each color to each group.

ggplot(test, 
       aes(y = Name, x = Value, fill = School, alpha = Alpha)) +
  geom_bar(stat = "identity", position = "dodge", color = "grey50") +
  scale_alpha_identity() 

I tried adding fill = df$Color inside geom_bar(), I also tried to change it to a factor (fill = as.factor(df$Color)) but the bars become stacked instead of staying grouped. I still have troubles understanding ggplot2 syntax and I guess I am overlooking something simple here...

EDIT: what I would like to change is the filling of the bars, where each Name should have its own filling (according to the Name itself, as specified in df$Color), and then a different transparency to distinguish between School.

2

There are 2 best solutions below

1
George Savva On BEST ANSWER

Using scale_alpha_manual allows you to map alpha values to schools (without using the alpha column in the data frame). The problem is then what should the legend look like since all the bars are different colours? You'd probably have to add a label to each bar.

ggplot(test, 
       aes(y = Name, x = Value, fill = Color,alpha=School)) +
  geom_bar(stat = "identity", position = "dodge", color = "grey50") +
  scale_fill_identity() + 
  scale_alpha_manual(values=c("A"=0.9, "B"=0.4))

enter image description here

2
Umar On

Following your code I have used similar approach where, I used both fill = School and alpha = Alpha in the main aes argument, making transparency dependent on the "Alpha" column. Fill colors are determined by the "School" variable.

library(tidyverse)

ggplot(test, 
       aes(y = Name, x = Value, fill = School, alpha = Alpha, color = Color)) +
  geom_bar(stat = "identity", position = "dodge") + #optionla ,color = "grey50" can be kept inside bracket here
  scale_alpha_identity() +
  scale_fill_manual(values = c("A" = "#E55C30FF", "B" = "#FBB91FFF")) +
  scale_color_identity()

enter image description here