在ggplot中更改默认的颜色调色板

40

我编写了一个返回颜色名称向量的函数:

custom.colors <- function(n) {
  palette <- c("dodgerblue1", "skyblue4", "chocolate1", "seagreen4",
               "bisque3", "red4", "purple4", "mediumpurple3",
               "maroon", "dodgerblue4", "skyblue2", "darkcyan",
               "darkslategray3", "lightgreen", "bisque",
               "palevioletred1", "black", "gray79", "lightsalmon4",
               "darkgoldenrod1")
  if (n > length(palette))
    warning('palette has duplicated colours')
  rep(palette, length.out=n)
}
我希望ggplot能够默认使用上述函数生成调色板。也许仅适用于离散比例尺。每次使用scale_manual()都太麻烦了。这可行吗?

7
这篇帖子应该很有用。 - baptiste
谢谢。我会记下来,但现在我卡在0.8.9版本了。 - Ernest A
4个回答

26

17天前(2020-05-19),Carson Sievert的工作已经被合并到ggplot2的开发版本中,该版本允许使用选项(ggplot2.discrete.fillggplot2.discrete.colour)指定默认的离散颜色调色板:

options(ggplot2.discrete.colour= c("red", "#af01ef"))

它还允许指定多个不同尺寸的托盘(使用足够小的托盘):

options(ggplot2.discrete.colour= list(c("red", "#af01ef"), custom.colors(99)))

不幸的是,它不接受一个调色板函数(比如你的custom.colors),但它接受一个刻度函数(所以你可以像@ernestA的答案中所述构建一个函数来产生你想要的警告)。

NEWS中得知:

默认离散颜色比例现在可以通过ggplot2.discrete.colourggplot2.discrete.filloptions()进行配置。当设置为足够长度的颜色代码字符向量(或字符向量列表)时,这些颜色将用于默认比例尺。有关更多详细信息和示例,请参见help(scale_colour_discrete)(@cpsievert,#3833)。


我不得不使用拼写为“colour”才能使其工作:options(ggplot2.discrete.colour = c("red", "#af01ef")) - JohannesNE
是的,谢谢!(有关此问题的一些见解:https://github.com/tidyverse/ggplot2/issues/4626) - jan-glx

21

如果您想重新定义默认的颜色比例尺,您可以仅仅重新定义 ggplot 函数:

ggplot <- function(...) ggplot2::ggplot(...) + scale_color_brewer(palette="Spectral")

对于填充比例,同样适用。


简单而美丽。 - Peque
20
将连续变量映射到颜色可能会引起麻烦。 - baptiste

10

@baptiste指向了一个帖子,其中提到了函数set_default_scale,可以用于设置默认调色板。下面的解决方案只适用于旧版本的ggplot2。

首先,我们需要一个生成颜色名称或代码的函数。我称之为magazine.colours

magazine.colours <- function(n, set=NULL) {
  set <- match.arg(set, c('1', '2'))
  palette <- c("red4", "darkslategray3", "dodgerblue1", "darkcyan",
               "gray79", "black", "skyblue2", "dodgerblue4",
               "purple4", "maroon", "chocolate1", "bisque3", "bisque",
               "seagreen4", "lightgreen", "skyblue4", "mediumpurple3",
               "palevioletred1", "lightsalmon4", "darkgoldenrod1")
  if (set == 2)
    palette <- rev(palette)
  if (n > length(palette))
    warning('generated palette has duplicated colours')
  rep(palette, length.out=n)
}

(它接受一个可选的 set 参数,只是为了说明你并不局限于一个调色板。) 现在我们创建一个“比例尺”,我称之为magazine。它基于ggplot的brewer比例尺,代码相当丑陋:

ScaleMagazine <- proto(ScaleColour, expr={
  objname <- 'magazine'
  new <- function(., name=NULL, set=NULL, na.colour='yellowgreen',
                  limits=NULL, breaks = NULL, labels=NULL,
                  formatter = identity, variable, legend = TRUE) {
    b_and_l <- check_breaks_and_labels(breaks, labels)
    .$proto(name=name, set=set, .input=variable, .output=variable,
            .labels = b_and_l$labels, breaks = b_and_l$breaks,
            limits= limits, formatter = formatter, legend = legend,
            na.colour = na.colour)
  }
  output_set <- function(.) {
    missing <- is.na(.$input_set())
    n <- sum(!missing)
    palette <- magazine.colours(n, .$set)
    missing_colour(palette, missing, .$na.colour)
  }
  max_levels <- function(.) Inf
})
scale_colour_magazine <- ScaleMagazine$build_accessor(list(variable = '"colour"'))
scale_fill_magazine <- ScaleMagazine$build_accessor(list(variable = '"fill"'))
重要的是要定义output_set函数,这是ggplot调用以获取颜色名称/代码的函数。而且,如果您需要额外的参数,则必须包含在new中,稍后可以作为.$argument_name访问。在上面的示例中,output_set仅调用magazine.colours
现在,请检查新比例尺是否实际上有效:
qplot(mpg, wt, data=mtcars, shape=21,
      colour=factor(carb), fill=factor(carb)) +
  scale_colour_magazine(set='1') +
  scale_fill_magazine(set='1')
要将其设置为默认值,只需使用 set_default_scale
set_default_scale("colour", "discrete", "magazine") 
set_default_scale("fill", "discrete", "magazine") 

就这样了。

> qplot(mpg, wt, data=mtcars, colour=factor(carb), fill=factor(carb))

显示新调色板的图表


6

只需分配一个变量,并使用您所需比例的名称:

scale_colour_discrete <- function(...)
  scale_colour_manual(..., values = c('dodgerblue1', *))

这样做是有效的,因为ggplot会尽可能地从全局环境中获取默认比例,类似于以下方式:
get('scale_colour_discrete', envir = globalenv())

我无法让它正常工作。你能提供一个可行的例子吗? - Sebastian Sauer
在交互式的 R 会话中,根据您想要使用离散或连续值的比例尺,以及根据您想要用于颜色或填充的比例尺,您必须定义一个名为 scale_{colour,fill}_{discrete,continuous} 的变量,例如 scale_colour_discrete <- scale_colour_viridis_d; ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) + geom_point() - flying sheep
4
注意:这仅在全局环境中执行代码时有效。如果在函数环境中使用ggplot2代码,则无法正常工作。 - pat-s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接