Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Issue with scale_color_identity() in ggplot — labels reordered automatically by colour name

I want to control my font colour using explicitly named colours in the label_col column. However, it seems that the colours "black" and "white" end up being ordered alphabetically by the colour name, instead of following the same fill and position specified in ggplot(aes()) and geom_col().

Here is my minimal example with black and white:

list_order <- c("a", "b", "c", "d", "e", "f")

test <- data.frame(indicator = rep(list_order, 2),
                   mean = c(1.1, 0.3, 6.3, 4, 7, 2.1, 1.2, 0.7, 6.9, 3.3, 5.4, 1.8),
                   group = c(rep("Group A", 6), rep("Group B", 6)))

test %>% 
  mutate(indicator = factor(indicator, levels = list_order),
         label = round(mean, 1),
         label_col = ifelse(indicator %in% c("a", "d", "e", "f"), "black", "white")) %>% 
  ggplot(aes(x = group, y = mean, fill = indicator)) +
  geom_col(width = 0.7, position = "stack") +
  geom_text(aes(label = label, color = label_col), size = 3, position = position_stack(vjust = 0.5)) +
  scale_color_identity() +
  scale_fill_viridis(discrete = T, option = "plasma")

Which gives me this:
enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If I change the colours in label_col to both "white", or both "black", I get them in the correct places like here:

enter image description here

enter image description here

Is there something I am not understanding about how ggplot positions labels and text? I know how to work around this by using scale_color_manual(), but would also like to understand why scale_color_identity() is not working here, and the solution for it.

>Solution :

The problem is with no explicit grouping of variables. I modified your code by adding group = group to aesthetics specification and it seem to work.

I am not entirely sure where specifically lies the problem, but I assume that the problem is with some reordering done under the hood — you can see in your example that all white labels are brought to the bottom and all black are brought to the top.

test %>% 
  mutate(indicator = factor(indicator, levels = list_order),
         label = round(mean, 1),
         label_col = ifelse(indicator %in% c("a", "d", "e", "f"), "black", "white")) %>% 
  ggplot(aes(x = group, y = mean, fill = indicator, group = group)) +
  geom_col(width = 0.7, position = "stack") +
  geom_text(aes(label = label, color = label_col), size = 3, position = position_stack(vjust = 0.5)) +
  scale_color_identity() +
  scale_fill_viridis(discrete = T, option = "plasma")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading