R语言 在自定义ggplot2中自动检测离散或连续调色板

kzipqqlq  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(88)

我正在开发一个名为ipeaplot的包,用于主题和调色板标准化。我们所做的尝试之一是创建一个scale_color()函数,该函数能够区分用户传递的是连续列还是离散列(例如,如果列类是数字或整数,则刻度选择应该是连续的,否则应该是离散的)
下面是代码示例

# Install package
remotes::install_github("ipeadata-lab/ipeaplot")
library(ggplot2)
library(ipeaplot)

字符串
这段代码可以工作,但请注意,我必须指定,我想要的是一个连续的规模

ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
  geom_point() + 
  scale_color_ipea(discrete = F)


此代码返回以下错误:“错误:连续值提供给离散刻度”

ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
  geom_point() + 
  scale_color_ipea(discrete = T)


因此,我需要手动设置scale_color_ipea(discrete = T),但我希望该函数能够自动检测列的类,并相应地使用适当的色标。

ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
  geom_point() + 
  scale_color_ipea(discrete = T)


有没有人能给我一个建议,告诉我如何做到这一点?

c9qzyr3d

c9qzyr3d1#

我会在这里为扩展您的包留出空间,让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")))
}

字符串
这现在允许:

ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
  geom_point() +
  scale_color_ipea()


的数据

ggplot(data = mtcars, aes(x = mpg, y = hp, color = factor(gear))) +
  geom_point() +
  scale_color_ipea()



这里有一些警告。一个完整的实现可能需要向后遍历plot对象中的所有层,如果颜色仅在基本ggplot调用之后定义,(经常发生)。每个层都需要评估其mappingdata,以确定颜色是否专门Map到那里而不是继承。在真实的实现中,您当然会将您的离散和连续调色板功能,以保持您的代码整洁和灵活。

相关问题