The issue is that in blogpost you linked the author makes use of colorRampPalette
to return an interpolated color palette for any number of colors. The first color will always be the first element and the last one the last element of the color vector you passed as input to colorRampPalette
. And in case of three colors you get the mid element too.
In general the palette
argument of ggplot2::discrete_scale
should be a function which takes one argument n
and returns n
colors.
One option to achieve your desired result may look like so where besides the palette function my_pal
I added a custom scale_color_my
function:
Note: My simple function does not do any checks and throws no warnings e.g. in case you demand more colors than provided by the color palette. Anyway, if you want to go further I would suggest to have a look a the source code of e.g. ggplot::scale_color_brewer
and scales::brewer_pal
.
my_pal <- function(n) {
cols <- c(
"#00AD2E", "#29C29E", "#2B8DAB", "#00A1DB", "#0C41ED", "#8B00F5",
"#C724F5", "#EF4E8E", "#F63131", "#F66223", "#FA85A6", "#F5910F",
"#F0BC00", "#D6901F", "#8D7F6D", "#8F8F8F", "#73B823", "#FF4D6A",
"#B1652F", "#1DAA76"
)
cols[seq_len(n)]
}
scale_colour_my <- function() {
discrete_scale("colour", "mypal", my_pal)
}
scale_color_my <- scale_colour_my
library(ggplot2)
d <- data.frame(
x = 1:12,
y = 1:12,
color4 = LETTERS[1:4],
color12 = LETTERS[1:12]
)
base <- ggplot(d, aes(x, y)) +
geom_point() +
scale_color_my()
base +
aes(color = color4)

base +
aes(color = color12)

EDIT If you want to account for multiple palettes you could follow the source code of scale_color_brewer
:
my_pal <- function(palette = "my1") {
cols <- c(
"#00AD2E", "#29C29E", "#2B8DAB", "#00A1DB", "#0C41ED", "#8B00F5",
"#C724F5", "#EF4E8E", "#F63131", "#F66223", "#FA85A6", "#F5910F",
"#F0BC00", "#D6901F", "#8D7F6D", "#8F8F8F", "#73B823", "#FF4D6A",
"#B1652F", "#1DAA76"
)
pal <- if (palette == "my1") {
cols
} else if (palette == "my2") {
rev(cols)
} else {
cols
}
function(n) {
pal[seq_len(n)]
}
}
scale_colour_my <- function(..., palette = "my1") {
discrete_scale("colour", "mypal", my_pal(palette = palette))
}
scale_color_my <- scale_colour_my
library(ggplot2)
d <- data.frame(
x = 1:12,
y = 1:12,
color4 = LETTERS[1:4],
color12 = LETTERS[1:12]
)
base <- ggplot(d, aes(x, y)) +
geom_point() +
aes(color = color4)
base +
scale_color_my()

base +
scale_color_my(palette = "my2")
