Заранее хочу извиниться за плохой английский ...
Я определил именованные, пользовательские цветовые палитры и хочу легко вызывать их с помощью собственной функции при создании графика с помощью функции ggplot (). Поэтому я кодировал «scale_function ()», для которого нужны только 3 параметра:
type (character. "color" or "fill" for aesthetic mapping)
palette (character. Name of an available palette)
discrete (logical. TRUE for discrete data and FALSE for continuous data)
. С помощью второй функции я использую (grDevices: :) colorRampPalette () для интерполяции заданных цветов палитры.
Пока все работает нормально, как и планировалось. Теперь я заметил очень специфическую проблему при использовании моей функции:
Допустим, мы хотим создать график, в котором нам нужно меньше цветов (n), чем на самом деле имеет моя выбранная цветовая палитра (c). Это означает, что n
palette_catalog является списком, а "palette_x" включает в себя 6 различных цветов в виде шестнадцатеричных кодов
palette_catalog[["palette_x"]]
# [1] "#d11141" "#00b159" "#00aedb" "#f37735" "#ffc425" "#cccccc"
plot
test <- ggplot(iris, aes(Sepal.Width, Sepal.Length, color = Species)) +
geom_point() +
scale_function(palette = "palette_x")
Теперь, если япроверка выбранных цветов на графике «тест». Я обнаружил следующую проблему:
Первый и последний цвет (шестнадцатеричный код) определенной палитры используется правильно, но промежуточный цвет будет интерполирован, потому чтоиспользования colorRampPalette ... следовательно, исходный шестнадцатеричный код перезаписывается интерполированным новым шестнадцатеричным кодом. -> это главная проблема! В целях согласованности ggplot2 :: discrete_scale () не должна вести себя так ...
Если на графике нужно больше цветов, чем может предложить палитра (n> c), результат будет абсолютно хорошим иправильно, но я бы хотел обойти интерполяцию, когда n
palette_catalog <- list(
palette_x = c(
"#d11141" (first value),
"#00b159",
"#00aedb",
"#f37735",
"#ffc425",
"#cccccc" (last value)
)
)
В двух словах: если для графика требуется, например, 3 значения цвета, то яхочу, чтобы discrete_scale () выбрал первое, второе и третье значение «palette_x» вместо первого, интерполированного среднего и последнего значения ...
Мне очень жаль, что я запутался в английском, я пробовалвсе возможное, чтобы описать мою проблему, и, надеюсь, вы поймете мою точку зрения ...
############### некоторый код, который должен работать (уменьшен до минимума), просто скопируйте вставить вВаш RStudio
palette_catalog <- list(
palette_x = c(
"#d11141",
"#00b159",
"#00aedb",
"#f37735",
"#ffc425",
"#cccccc"
)
)
interpolate <- function(palette = "palette_x", ...) {
x <- palette_catalog[[palette]]
colorRampPalette(x, ...)
}
scale_function <- function(
type = "color",
palette = "palette_x",
discrete = TRUE,
...) {
count <- length(palette_catalog[[palette]])
pal <- interpolate(palette)
if(type == "color") {
if(discrete) {
discrete_scale("color", palette, palette = pal, ...)
} else {
scale_color_gradientn(colors = pal(count), ...)
}
}
}
### use this code on this standard plot with iris dataset:
ggplot(iris, aes(Sepal.Width, Sepal.Length, color = Species)) +
geom_point() +
scale_function(palette = "palette_x")
![enter image description here](https://i.stack.imgur.com/cq2Ei.png)
## you can print the used colors of a plot with the following code:
plot <- ggplot(iris, aes(Sepal.Width, Sepal.Length, color = Species)) +
geom_point() +
scale_function(palette = "palette_x")
gg <- ggplot_build(plot)
unique(gg$data[[1]]["colour"])
# colour
# 1 #D11141
# 51 #799288
# 101 #CCCCCC
ожидаемые (обязательные) цвета, используемые для 3 различных видов:
первые тризначения цвета "palette_x" в таком порядке:
"#d11141",
"#00b159",
"#00aedb"
фактические, неправильные цвета, использованные для графика:
, как уже дразнили в начале, график использует первый, средний (интерполированный)и последние значения цвета ...
"#d11141",
"#799288",
"#cccccc
Как вы видитеЗначение второго цвета недопустимо, поскольку оно является результатом интерполяции и не совпадает с фактическим вторым значением «palette_x», которое должно быть «# 00b159».
Кроме того, третье значение цвета также не запрашивается. Вместо этого должно было быть выбрано фактическое третье значение, которое является "# 00aedb".
Я действительно надеюсь, что кто-то может помочь мне и найти решение! Я уверен, что есть одно.
Я пробовал несколько решений, но ни одно из них не сработало ...
Код работает просто отлично, как я уже сказал. Просто этот крошечный конкретный случай - боль в заднице, и R сводит меня с ума в этот момент ... потому что ничто не работает так, как я ожидаю, что это должно ...
Буду признателен за вашу помощь и поддержку!