ggplot2 icon indicating copy to clipboard operation
ggplot2 copied to clipboard

unexpected behavior when setting named vector for default colour/fill

Open mjsmith037 opened this issue 3 years ago • 4 comments

First, thanks for adding this functionality to ggplot2 - it has been enormously useful in my day-to-day coding. Now on to the issue:

When setting a default color palette using ggplot2.options.discrete.colour or ggplot2.options.discrete.fill, the plotting function will only pull a subset of the submitted vector of length equal to the number of unique colours needed. This works fine for unnamed color vectors, however it has undesirable behavior when the relevant named elements occur outside of this subset.

library(ggplot2)
options(ggplot2.discrete.fill=c("4"="red", "8"="blue", "6"="green"))
data(mpg)

# removing 5 here for a cleaner plot; works as expected
ggplot(mpg[mpg$cyl != 5,]) +
  aes(x=hwy, fill=factor(cyl)) +
  geom_density()

# note that even though we have a colour named "6" in the above vector, ggplot2
# does not find it and instead uses the NA fill
ggplot(mpg[mpg$cyl != 5 & mpg$cyl != 8,]) +
  aes(x=hwy, fill=factor(cyl)) +
  geom_density()

Created on 2022-10-14 by the reprex package (v2.0.1)

mjsmith037 avatar Oct 14 '22 15:10 mjsmith037

did you want to use scale fill manual ? this is not how scale discrete is to be used

smouksassi avatar Oct 17 '22 09:10 smouksassi

By "is to be used," do you mean default discrete scales should not be named? I guess I might come to understand a principled stand on this, however it would avoid confusion if these scales were then unname()d (ideally with a warning) on the back end. Documentation could also go a long way toward specifying desired use. As it is, I found the use I outlined above intuitive outside of this particular instance of mismatch.

mjsmith037 avatar Oct 19 '22 02:10 mjsmith037

Thanks for catching. I too feel it's a bit confusing at least that the behavior is different from scale_fill_manual()...

library(ggplot2)

ggplot(mpg[mpg$cyl != 5 & mpg$cyl != 8,]) +
  aes(x=hwy, fill=factor(cyl)) +
  geom_density() +
  scale_fill_manual(values = c("4"="red", "8"="blue", "6"="green"))

Created on 2022-11-05 with reprex v2.0.2

yutannihilation avatar Nov 05 '22 05:11 yutannihilation

The issue would be resolved if we remove the [seq_len(n)] in the line below:

https://github.com/tidyverse/ggplot2/blob/ed6afe509071ac48cca3c9b0b6cd48b5de80b1f1/R/scale-hue.R#L224

But perhaps the broader question is whether we want to support named palettes in the options?

teunbrand avatar Apr 22 '24 12:04 teunbrand