How properly use scale_fill_manual() and its arguments labels(), breaks(), limits() - colours being messed up!

Hi everyone,
I am trying to plot this barplot, with selected colours (manually) for my_dataframe.

head(my_dataframe)
pop individ K coefficient_q Genotype
Region A 1 K1 0.95 K1_PURE
Region A 1 K2 0.05 K2_PURE
Region B 2 K1 0.98 K1_Mismatch
Region B 2 K2 0.02 K2_Mismatch
... ... ... ... ...

I filtered my_dataframe, to eliminate one of the Regions that I don't want to plot (i.e. Region A), which also means i have 0 counts now for 2 of the Genotype levels.
I want to plot each Genotype with a different colour, but I want to display in the legend only the first 4 labels of the Genotypes. The code I used is below.
The problem is that, I get each Genotype class with the colour I want if I don't add the argument "limits(c( "K1_Mismatch1","K1_PURE1", "K2_Mismatch1", "K2_PURE" )". As soon as I add "limits()", I get most of my bars (so most of my Genotype classes) coloured "grey" (which is not even listed in my colours values!!).
Why is that happening?

Isn't limits supposed to list all the labels you want to show up in the legend and not affect the colour of the factor variable you are filling your bar with?

Also, what is the difference in using "breaks" and "labels"?? How can I be sure that each Genotype factor category has been assigned the correct colour I want it to assigned? Which argument in the code of scale_fill_manual() is responsible for this?

I would appreciate some help as I am breaking my head on this!!
Thanks a lot!
Gabriella

--> CODE below:
'''
my_dataframe %>%
mutate(pop = fct_relevel(pop,
"Region A", "Region B"," Region C "," Region D "," Region E ",
" Region F "," Region G"," Region H"," Region I"," Region L",
" Region M"," Region N")) %>%
ggplot() +
geom_col(aes(x = indiv, y = coefficient_q, fill = Genotype)) +
scale_fill_manual(
values = c("lightblue", "slateblue", "rosybrown1",
"tomato", "lightblue", "slateblue", "rosybrown1","tomato"),
labels = c("K1_Mismatch1","K1_PURE1", "K2_Mismatch1", "K2_PURE", "K1_Mismatch2", "K1_PURE2","K2_Mismatch1","K2_PURE2"),
breaks = c("K1_Mismatch1","K1_PURE1", "K2_Mismatch1", "K2_PURE", "K1_Mismatch2", "K1_PURE2", "K2_Mismatch1","K2_PURE2"),
limits = c( "K1_Mismatch1","K1_PURE1", "K2_Mismatch1", "K2_PURE" )) +
facet_wrap( ~ pop, scales="free_x", labeller = labeller(pop = pop)) +
labs(fill = "K")

'''

Compare the four plots in the following code. I hope it helps you understand the use of values, breaks and labels.

DF <- data.frame(Grp = c("A","B","C","D"),
                 Val = c(3,5,4,2))
ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  #use values to set the colors used for the levels in the Grp column
  scale_fill_manual(values = c(A = "red", B= "blue", C = "green", D = "orange"))

ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  #use breaks to change the order displayed in the legend
  scale_fill_manual(values = c(A = "red", B = "blue",  C = "green", D = "orange"),
                    breaks = c("A","C","D","B"))

ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  #use labels to change the text diplayed in the legend
  scale_fill_manual(values = c(A = "red", B = "blue",  C = "green", D = "orange"),
                    breaks = c("A","C","D","B"),
                    labels = c("W","X","Y","Z"))

ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  #If no value is assigned for B, it becomes gray in the plot and is not shown in the legend
  scale_fill_manual(values = c(A = "red",  C = "green", D = "orange"),
                    breaks = c("A","C","D","B"),
                    labels = c("W","X","Y","Z"))
1 Like

Oops, I forgot to demonstrate the use of limits.

ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  #limits can also reorder the legend. Leaving a level out of limits makes the
  #bar gray
  scale_fill_manual(values = c(A = "red", B = "blue",  C = "green", D = "orange"),
                    limits = c("B","C","A","D"))
1 Like

Hi FJCC,
and thank you so much for the example plots. They were really useful!
However, even using the option you suggested with values = c(a= "red", ...) & limits=(c("b", "c", "a", "d") does not work for me, because I want to show only 4 out of the 8 legend items, and that's why I wanted to use limits as exemplified here -->how keep aesthetic mapping but remove a specific item from legend with ggplot - #3 by dromano

But, if I use limits=c() and I list only the first 4 elements of my fill variable, then I get most bars grey... this seems to reflect what you said about leaving a value out of limits, which turns those bars grey...how can I avoid that? Is there a way to limit the elements shown in the legend to only 4 out of 8, but retain the assigned colours for each fill category?

I am not sure if I explained it well..
Thank you for your help!
Gabriella

You mean like this:

ggplot(DF, aes(Grp, Val, fill = Grp)) + geom_col() +
  scale_fill_manual(values = c(A = "red", B = "blue",  C = "green", D = "orange"),
                    breaks = c("A","B"))

grafik

In the discussion you linked it's also said to ue the breaks argument for that.

1 Like

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.