Reputation: 23767
On pondering on this very recent question I noticed that reversing the factor levels does naturally not change the order of colors. I tried to add direction = -1
in scale_fill
/scale_color
("_discrete
" and "_hue
"), and was stunned by the weird result. I am not sure if there are more recent questions than this thread, but the given code does produce the following weird result (regardless of the h.start
argument). The same happens with fill
Bug? Or am I overlooking something?
(P.s. I don't really like the default colors and am never really using them. This is more of an academic question)
library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point() +
scale_color_discrete(direction = -1)
Created on 2020-02-04 by the reprex package (v0.3.0)
devtools::session_info()
#> version R version 3.6.2 (2019-12-12)
#> ggplot2 * 3.2.1 2019-08-10 [1] CRAN (R 3.6.1)
Upvotes: 0
Views: 1645
Reputation: 8506
I believe it is a bug in the scales::hue_pal
function. In that help page, one example is show_col(hue_pal(direction = -1)(9))
, which (on my machine) gives the same color as in your example in all 9 tiles - and that is certainly not the intended outcome.
It seems like farver:::encode_c does not work as intended in that context.
Intuitively, I would just reverse the palette you get with direction=1
, but the scales::hue_pal
function generates negative hues that farver::encode_colour
cannot deal with.
I am not sure this is the intended outcome (just reversing the order of the palette colors), but I would adjust the scales::hue_pal
function like this:
library(ggplot2)
library(scales)
hue_pal <- function (h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, direction = -1)
{
stopifnot(length(h) == 2)
stopifnot(length(c) == 1)
stopifnot(length(l) == 1)
scales:::force_all(h, c, l, h.start, direction)
function(n) {
if (n == 0) {
stop("Must request at least one colour from a hue palette.",
call. = FALSE)
}
if ((diff(h)%%360) < 1) {
h[2] <- h[2] - 360/n
}
rotate <- function(x) (x + h.start)%%360 * direction
hues <- rotate(seq(h[1], h[2], length.out = n))
if(direction == -1) hues <- abs(rev(hues)) # my edit
hcl <- cbind(hues, c, l)
farver::encode_colour(hcl, from = "hcl")
}
}
scale_color_discrete <- function (..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0,
direction = 1, na.value = "grey50", aesthetics = "colour")
{
discrete_scale(aesthetics, "hue", hue_pal(h, c, l, h.start,
direction), na.value = na.value, ...)
}
# reversed color palette
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point() +
scale_color_discrete(direction = -1)
# standard palette
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point() +
scale_color_discrete(direction = 1)
Created on 2020-02-04 by the reprex package (v0.3.0)
Upvotes: 1