【发布时间】:2019-10-01 20:23:39
【问题描述】:
在此之前,我想为我糟糕的英语道歉......
我定义了命名的自定义调色板,并希望在使用函数 ggplot() 创建绘图时使用自创函数轻松调用它们。因此我编写了一个只需要 3 个参数的“scale_function()”:
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"
情节
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”的第一个、第二个和第三个值,而不是第一个、插值的中间值和最后一个值...
我真的很抱歉我的英语混乱,我已经尽力描述我的问题,希望你能理解我的意思......
############## 一些应该可以工作的代码(减少到最低限度),只需将粘贴复制到您的 RStudiopalette_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")
## 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 让我发疯......因为没有什么能像我预期的那样工作......
感谢您的帮助和支持!
【问题讨论】: