我正在开发一个名为ipeaplot主题和调色板标准化的包。我们所做的尝试之一是创建一个scale_color()能够区分用户传递的是连续列还是离散列的函数(例如,如果列类是数字或整数,则尺度选择应该是连续的,否则应该是离散的)
下面是代码示例
# Install package
remotes::install_github("ipeadata-lab/ipeaplot")
library(ggplot2)
library(ipeaplot)
Run Code Online (Sandbox Code Playgroud)
这段代码可以工作,但是请注意我必须指定我想要的是连续的比例
ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
geom_point() +
scale_color_ipea(discrete = F)
Run Code Online (Sandbox Code Playgroud)
此代码返回以下错误:“错误:向离散刻度提供连续值”
ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
geom_point() +
scale_color_ipea(discrete = T)
Run Code Online (Sandbox Code Playgroud)
所以我需要手动设置,scale_color_ipea(discrete = T)但我希望该功能能够自动检测列的类别并相应地使用足够的色标。
ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
geom_point() +
scale_color_ipea(discrete = T)
Run Code Online (Sandbox Code Playgroud)
有人会建议如何做到这一点吗?
scale_color_ipea我将通过创建 S3 类对象,然后定义一个方法,为扩展您的包留出空间ggplot_add。
此机制允许您询问绘图对象,以根据数据类型完全自动选择离散或连续比例。
scale_color_ipea <- function(discrete = FALSE, ...) {
structure(list(...), class = "scale_chooser")
}
ggplot_add.scale_chooser <- function(object, plot, name) {
args <- object
var <- rlang::eval_tidy(rlang::quo_squash(plot$mapping$colour), plot$data)
discrete <- !is.numeric(var)
if(discrete) {
return(plot +
do.call("discrete_scale",
c(list(aesthetics = "color", scale_name = "ipea",
palette = colorRampPalette(c("red", "green", "blue"))),
args)))
}
return(plot +
do.call("continuous_scale",
c(list(aesthetics = "color", scale_name = "ipea",
palette = function(x) {
colorRamp(c("red", "green", "blue"))(x) |>
apply(1, \(x) do.call("rgb", as.list(x/255)))
}), args, guide = "colourbar")))
}
Run Code Online (Sandbox Code Playgroud)
现在允许:
ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
geom_point() +
scale_color_ipea()
Run Code Online (Sandbox Code Playgroud)
ggplot(data = mtcars, aes(x = mpg, y = hp, color = factor(gear))) +
geom_point() +
scale_color_ipea()
Run Code Online (Sandbox Code Playgroud)
这里有一些注意事项。完整的实现可能需要向后迭代绘图对象中的所有图层,以防颜色仅在基本 ggplot 调用之后定义(这种情况经常发生)。每个层都需要对其mapping进行data评估,以确定颜色是否是专门映射到那里的而不是继承的。在现实世界的实现中,您当然也会将离散和连续调色板函数分开,以保持代码整洁和灵活。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |