是否可以轻松地使 ggplot 去饱和?

Is it possible to desaturate a ggplot easily?

是否可以轻松去除 ggplot 的饱和度?


原则上,可能有两种可能的策略。
首先,将一些函数应用于 ggplot 对象(或者可能是 Grob 对象)以降低所有颜色的饱和度。其次,在渲染 .rmd 文件时打印 ggplot 去饱和的一些技巧。这两种策略对我来说都可以,但第一种当然更有前途。
从一开始就用灰色创建 ggplot 不是一个好的选择,因为这个想法是要有相同的图,就好像它是用灰色阴影打印的一样。


关于如何在 R 中执行去饱和,有一些类似的问题和非常好的答案。Here is a convenient way to desaturate color palette. And 是对光栅图像进行去饱和的方法。我正在寻找的是一种使整个 ggplot 去饱和的简单方法。

根据我上面的评论,这可能是 quickest/dirtiest 实现 ggplot2 对象去饱和的方法:

library(ggplot2)

set.seed(1)
p <- qplot(rnorm(50), rnorm(50), col="Class")
print(p)

pdf(file="p.pdf", colormodel="grey")
  print(p)
dev.off()

我尝试使用新的 viridis 调色板进行此操作,因为它可以很好地去饱和(即它应该在彩色和非彩色图之间很明显):

library(ggplot2)
library(grid)
library(colorspace)
library(viridis) # devtools::install_github("sjmgarnier/viridis") for scale_fill_viridis

gg <- ggplot(mtcars) + 
  geom_point(aes(x=mpg, y=wt, fill=factor(cyl), size=factor(carb)), 
             color="black", shape=21) + 
  scale_fill_viridis(discrete = TRUE) +
  scale_size_manual(values = c(3, 6, 9, 12, 15, 18)) +
  facet_wrap(~am)

gb <- ggplot_build(gg)
gb$data[[1]]$colour <- desaturate(gb$data[[1]]$colour)
gb$data[[1]]$fill <- desaturate(gb$data[[1]]$fill)

gt <- ggplot_gtable(gb)

grid.newpage()
grid.draw(gt)

你最终不得不在 grob 级别上进行操作。

这是去饱和前的图:

这是情节post-desature:

我想弄清楚为什么跳过图例,这可能会遗漏其他高度定制的 ggplot 美学和组件,所以即使它不是一个完整的答案,也许它可能有用(并且也许其他人可以继续使用它或在另一个答案中扩展它)。这应该只是替换 gb 对象或 gt 对象中的正确位的问题。

更新 我设法为图例找到了正确的 grob 元素:

gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[4]]$gp$fill <- 
    desaturate(gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[4]]$gp$fill)
gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[6]]$gp$fill <- 
    desaturate(gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[6]]$gp$fill)
gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[8]]$gp$fill <- 
    desaturate(gt$grobs[[12]][[1]][["99_9c27fc5147adbe9a3bdf887b25d29587"]]$grobs[[8]]$gp$fill)

grid.newpage()
grid.draw(gt)

寻找其他 gp 需要去饱和元素的阴谋也不错。

刚遇到这个问题。实验包 colorblindr(由 Claire McWhite 和我自己编写)包含一个可以以通用方式执行此操作的函数。我正在使用来自@hrbrmstr 的示例图:

library(ggplot2)
library(viridis)

gg <- ggplot(mtcars) + 
  geom_point(aes(x=mpg, y=wt, fill=factor(cyl), size=factor(carb)), 
             color="black", shape=21) + 
  scale_fill_viridis(discrete = TRUE) +
  scale_size_manual(values = c(3, 6, 9, 12, 15, 18)) +
  facet_wrap(~am)
gg

现在让我们使用 colorblindr 中的 edit_colors() 函数来降低这个图的饱和度:

library(colorblindr) # devtools::install_github("clauswilke/colorblindr")
library(colorspace) # install.packages("colorspace", repos = "http://R-Forge.R-project.org") --- colorblindr requires the development version
# need also install cowplot; current version on CRAN is fine.

gg_des <- edit_colors(gg, desaturate)
cowplot::ggdraw(gg_des)

函数 edit_colors() 获取一个 ggplot2 对象或 grob,并将颜色转换函数(此处 desaturate)应用于 grob 中的所有颜色。

我们可以为转换函数提供额外的参数,例如进行部分去饱和:

gg_des <- edit_colors(gg, desaturate, amount = 0.7)
cowplot::ggdraw(gg_des)

我们还可以做其他的转换,例如色盲模拟:

gg_des <- edit_colors(gg, deutan)
cowplot::ggdraw(gg_des)

最后,我们可以分别操作线条颜色和填充颜色。例如,我们可以将所有填充区域设为蓝色。 (不确定这是否有用,但无论如何。)

gg_des <- edit_colors(gg, fillfun = function(x) "lightblue")
cowplot::ggdraw(gg_des)