N. Sarkar
N. Sarkar

Reputation: 483

ggplot2 0.9.0 automatically dropping unused factor levels from plot legend?

I recently upgraded to ggplot2 0.9.0 from version 0.8.9, and now I'm getting that my plot legends only show the factor levels used in the plot (it omits the unused ones). Before it'd include all factor levels in the legend. I'm running Windows 7 and R 2.15.0 (2.14.2 before today).

Is anyone else finding this too? Is there a way I can get the unused factor levels to display in my plot legend?

library(ggplot2)

df <- data.frame(fruit = rep(c("apple", "orange"), times=11), 
                 year = 1990:2011, 
                 qty = rnorm(22, 100, 20))

# This plot only gives "apple" in the legend now.
# Before, I used to get both "apple" and "orange". 
qplot(year, qty, data = subset(df, fruit=="apple"), colour = fruit) 

The qplot() used to give me both "apple" and "orange" in the legend (even though there were only points for "apple"). Now I only get "apple" in the legend.

Reason this came up - I am making many plots of subsets of a data set and I want the legends standardized across plots (normally I'd appreciate the unused levels being automatically dropped and not having to type droplevels(), but this is the one case I want those unused levels). Apologies if this is a question local to my computer only.


Edit: Note that as of R 4.0.0, the above code no longer produces a df$fruit as a factor, which changes the behavior of ggplot in the question and answers below. To reproduce use:

df <- data.frame(
  fruit = factor(rep(c("apple", "orange"), times=11)), 
  year = 1990:2011, 
  qty = rnorm(22, 100, 20)
)

Upvotes: 47

Views: 15439

Answers (2)

Axeman
Axeman

Reputation: 35187

A second way is to explicitly define the required entries by using the limits argument:

ggplot(subset(df,fruit == "apple"),aes(x = year,y = qty,colour = fruit)) + 
  geom_point() + 
  scale_colour_discrete(limits = c("apple", "orange"))

Edit:

As of v3.5.0, ggplot2 tries to be smarter about what to include in legends. As an unfortunate side effect, using drop = TRUE or setting the limits will include the levels in the legend, but will not include glyphs (i.e. colored dots in this case). To return to the previous behavior, you need to set show.legend = TRUE in any geom you want to be included in your glyphs, e.g:

ggplot(subset(df,fruit == "apple"),aes(x = year,y = qty,colour = fruit)) + 
  geom_point(show.legend = TRUE) + 
  scale_colour_discrete(limits = c("apple", "orange"))

Upvotes: 16

joran
joran

Reputation: 173527

Yes, you want to add drop = FALSE to your colour scale:

ggplot(subset(df,fruit == "apple"),aes(x = year,y = qty,colour = fruit)) + 
    geom_point() + 
    scale_colour_discrete(drop = FALSE)

Upvotes: 56

Related Questions