ggplot:如何为所有几何元素设置默认颜色?

27
我想将ggplot中所有几何对象的默认颜色设置为除黑色以外的其他颜色。请注意,这与设置scale_color不同...
简单示例:
# linear model with confidence bands...
set.seed(1)
df <- data.frame(x=1:50, y=5 + 2*(1:50)+rnorm(50,sd=10))
lm <- lm(y~x,df)
se <- summary(lm)$sigma           # standard error of fit
Z  <- qnorm(0.05/2,lower.tail=F)  # 95% confidence bands
df <- cbind(df,predict(lm,se.fit=T)[c("fit","se.fit")])
# plot the result...
library(ggplot2)
ggplot(df, aes(x=x)) + 
  geom_point(aes(y=y), size=3) +
  geom_line(aes(y=fit)) +
  geom_line(aes(y=fit+Z*se.fit), linetype=2)+
  geom_line(aes(y=fit-Z*se.fit), linetype=2)

现在,假设我想让所有东西都变成红色。撇开这样做的明智性不谈,我认为ggplot(df, aes(x=x), colour="red")可以实现。但是colour=参数似乎被忽略了:一切仍然是黑色的。我可以在每个geom_调用中添加colour="red",但我试图避免这样做。 编辑: 使用ggplot(df, aes(x=x, color="red"))不是一个选项,因为它使用默认的ggplot调色板(均匀分布在HSL颜色圆周上)创建一个颜色比例尺。对于一个颜色,这是#F8766D,它恰好是浅红色。此外,这会创建一个需要隐藏的图例。

只是好奇,为什么你不想使用scale_color_呢? - PirateGrunt
@PirateGrunt 问题末尾的编辑有点解释了。我需要通过在ggplot调用中设置aes(...)中的颜色来创建一个颜色比例尺,然后使用类似于scale_color_manual(values="red", guide="none")的东西。这只是一个hack - 应该有更简单的方法。另外,假设我想在图中使用颜色比例尺来表示其他内容,例如基于某个分组变量对点进行着色并使其他所有内容都为红色。 - jlhoward
@PirateGrunt 另一个原因可能是为了暗色调的图表。这里唯一的挑战就是设置与几何相关的颜色(点、箱线图、线条等)。 - Saren Tasciyan
2个回答

32
您可以按如下方式为每个几何类型设置默认颜色:
update_geom_defaults("point",   list(colour = "red"))
update_geom_defaults("line",   list(colour = "red"))

ggplot(df, aes(x=x)) + 
  geom_point(aes(y=y), size=3) +
  geom_line(aes(y=fit)) +
  geom_line(aes(y=fit+Z*se.fit), linetype=2)+
  geom_line(aes(y=fit-Z*se.fit), linetype=2)

编辑 如果你想要做所有的事情,那么使用 (借用自这里):

params <- ls(pattern = '^geom_', env = as.environment('package:ggplot2'))
geoms <- gsub("geom_", "", params)

lapply(geoms, update_geom_defaults, list(colour = "red"))
lapply(geoms, update_geom_defaults, list(fill = "red", colour = "red")) ## include fills 

如果您想为单一绘图设置默认颜色,只需执行以下操作:
ggplot(df, aes(x=x, colour="red")) + 
  geom_point(aes(y=y), size=3) +
  geom_line(aes(y=fit)) +
  geom_line(aes(y=fit+Z*se.fit), linetype=2)+
  geom_line(aes(y=fit-Z*se.fit), linetype=2)

4
哇,我从未知道那个功能。太棒了。 - joran
谢谢,但这不是我想要的。我正在尝试为这个ggplot对象设置默认颜色,就像调用ggplot(df)会使df成为此对象的默认数据集一样。根据文档,update_geom_default(...)设置此会话中所有未来绘图的默认值。 - jlhoward
已经修正以反映这种区别。@Blue Magister,这个修改是你早些时候建议的吗?如果是,请重新提交以便归属! - metasequoia
2
@metasequoia 真是个棒极了的函数!不过,你的代码有一个问题,因为它将颜色美学映射到变量“red”,请尝试将其更改为“green”,你会发现线条和点仍然是红色的。 - americo
有没有一种方法可以使用多种颜色来完成这个任务,例如当有3个类别时使用geom_col。 - jzadra
@amzu 虽然 aes(colour = "red") 没有抛出任何错误,但从技术上讲是错误的。它将默认的 ggplot 颜色分配给所有数据,而不是红色。替代方法是 plot + scale_color_manual(breaks = NULL, values = "red") - Chirag

2
为了替换所有使用默认geom外观的geoms为其他外观,您可以尝试以下代码。 首先定义一个函数,用于从ggplot2中获取所有geoms的默认aes设置。
library(ggplot2)
library(purrr)

geom_aes_defaults <- function() {
  geom_names <- apropos("^Geom", ignore.case = FALSE)
  geoms <- mget(geom_names, env = asNamespace("ggplot2"))
  map(geoms, ~ .$default_aes)
}

使用geom_aes_defaults()函数,您可以获取所有几何美学映射的长列表。
$Geom
Aesthetic mapping:
<empty>

$GeomAbline
Aesthetic mapping:
* `colour`   -> "black"
* `size`     -> 0.5
* `linetype` -> 1
* `alpha`    -> NA

$GeomAnnotationMap
Aesthetic mapping:
* `colour`   -> "NA"
* `fill`     -> "grey20"
* `size`     -> 0.5
* `linetype` -> 1
* `alpha`    -> NA

$GeomArea
Aesthetic mapping:
* `colour`   -> NA
* `fill`     -> "grey20"
* `size`     -> 0.5
* `linetype` -> 1
* `alpha`    -> NA

...

以下函数遍历所有与给定美学匹配的几何图形,并替换相应的值。
replace_geom_aes_defaults <- function(name, old_aes, new_aes) {
  matching_geoms <- 
    map(geom_aes_defaults(), name) %>%
      compact() %>%
      keep(~ !is.na(.) & . == old_aes)
  geoms <- gsub("^Geom(.*)", "\\1", names(matching_geoms))
  walk(geoms, update_geom_defaults, setNames(list(new_aes), name))
}

现在您可以系统地替换颜色,例如通过将黑色变为红色:
replace_geom_aes_defaults("colour", "black", "red")

甚至可以将柱状图的填充颜色替换为

replace_geom_aes_defaults("fill", "grey35", "red")

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