减小色彩调色板的饱和度

16

我正在寻找一种函数,可以将给定的颜色调色板的饱和度减少一定量。例如,想象一下我有一个调色板:

library(colorRamps)    
col.palette=colorRampPalette(rainbow(13),interpolate ="spline")(1000)
pie(rep(1,1000), col=col.palette,lty=0,labels=NA)

enter image description here

有没有什么函数可以对这个col.palette颜色向量进行操作,降低一定的饱和度,或者允许改变亮度和对比度?(我试图实现一个彩虹调色板,其饱和度比标准调色板低,过渡更平滑)

编辑:我还发现在scales包中有一个名为muted的函数,基本上做了我想要的东西: http://www.inside-r.org/packages/cran/scales/docs/muted

还有在Josh O'Brien下面提到的colorspace包中的rainbow_hcl,这是我正在寻找的更柔和、强度均等的彩虹: http://www.inside-r.org/packages/cran/colorspace/docs/rainbow_hcl

library(colorspace)
pie(rep(1,1000), col=rainbow_hcl(1000,c=100,l=60),lty=0,labels=NA)

在此输入图片描述

3个回答

21

这里有一个函数,可以将输入颜色向量按指定比例去饱和度:

library(colorspace)   ## hsv colorspace manipulations
library(RColorBrewer) ## For some example colors

## Function for desaturating colors by specified proportion
desat <- function(cols, sat=0.5) {
    X <- diag(c(1, sat, 1)) %*% rgb2hsv(col2rgb(cols))
    hsv(X[1,], X[2,], X[3,])
}

这里是一个实际演示的例子:

## Utility function for plotting color palettes, 
## (from vignette("hcl-colors"))
pal <- function(col, border = "light gray", ...) {
  n <- length(col)
  plot(0, 0, type="n", xlim = c(0, 1), ylim = c(0, 1),
  axes = FALSE, xlab = "", ylab = "", ...)
  rect(0:(n-1)/n, 0, 1:n/n, 1, col = col, border = border)
}

## Some example colors
cc <- brewer.pal(9, 'Set1')
cc75 <- desat(cc, 0.75)
cc50 <- desat(cc, 0.50)
cc25 <- desat(cc, 0.25)

## Plot 'em
par(mfcol = c(4,1), mar = c(0,0,0,0))
pal(cc)
pal(cc75)
pal(cc50)
pal(cc25)

在此输入图片描述


1
非常感谢,这正是我想要的!不过似乎我还需要操纵V分量,以避免颜色看起来过于褪色... - Tom Wenseleers
2
@TomWenseleers -- 好的。如果你想到了什么聪明的方法,请考虑将其留在这里作为更好的答案。如果你还没有发现它,你可能会发现运行 colortools::choose_palette(rainbow_hcl) 很有趣,然后将绘图类型设置为 "Pie" 在结果 GUI 中探索一些选项。干杯。 - Josh O'Brien
我真的不认为这应该是被接受的正确解决方案。它将颜色朝向白色去饱和,而不是朝向灰色,我不认为这符合大多数用户的预期行为。 - user1521655

11

这似乎工作得很好:

col2 <- adjustcolor(col.palette,alpha.f=0.5)
pie(rep(1,1000), col=col2,lty=0,labels=NA)

adjustcolor 是 R 语言中的一个函数,它可以让你以多种方式调整颜色,但我认为 alpha.f 参数最有用。


1
谢谢您指出这个函数!在我的情况下,我不想改变alpha/透明度,因为它是用于3D rgl绘图的。虽然adjustcolor很好用,但似乎不允许轻松地操纵亮度、对比度和饱和度等内容(除非通过自定义转换来指定)。 - Tom Wenseleers
感谢@TomWenseleers的提示 - 我还需要在3D图表(rglwidget)中进行颜色转换。 - lambruscoAcido

3

这里有另一种方法。在rainbow()中,您可以使用两个更多的参数(即s和v)。s用于饱和度。如果您尝试调整这两个参数,您就能得到想要的效果。

col.palette=colorRampPalette(rainbow(13, s = 1, v = 0.8),interpolate = "spline")(1000)
pie(rep(1,1000), col=col.palette,lty=0,labels=NA)

enter image description here

col.palette=colorRampPalette(rainbow(13, s = 0.6, v = 1),interpolate = "spline")(1000)
pie(rep(1,1000), col=col.palette,lty=0,labels=NA)

enter image description here


非常感谢!这只适用于特定的彩虹调色板,而不是任何调色板,对吗? - Tom Wenseleers
@TomWenseleers 我做了一些搜索。你可能想看看 ?hsv。根据 R 文档,如果你使用 hsv() 创建颜色,函数返回的值可以与 col = 规范一起使用。因此,在绘制图形之前,你可以控制饱和度。 - jazzurro
哈,我明白了 - 所以基本上是将其转换为HSV,然后更改饱和度值,对吧?我刚刚尝试了 cols=colorRampPalette(rainbow(13),interpolate ="spline")(1000); cols=apply(sapply(cols,col2rgb),2,rgb2hsv); cols[2,]=cols[2,]/2;cols=apply(cols,2,hsv);pie(rep(1,1000), col=cols,lty=0,labels=NA) 但似乎不起作用 - 你认为我做错了什么? - Tom Wenseleers
@TomWenseleers 我在这个层面上还没有处理过颜色问题。但是,这是我的猜测。一旦你将 RGB 转换为 HSV,你就有了三行。第二行可能是 s,我猜测。如果你改变行中的值,你就可以控制饱和度;不需要使用 HSV。对于饼图,col 取一个颜色向量。你的 cols 仍然在矩阵中。我想你可能需要从 HSV 转换到 RGB,再转换为颜色。我看到一个帖子说 R 中没有 hsv2rgb 函数。这是我现在能做的最好的了。 - jazzurro
@TomWenseleers 再来一个。我检查了其他调色板,比如 heat.colorscm.colorstopo.colors。在这些函数中,我看到了 hsv。如果你需要使用这些函数,你可以修改它们。 - jazzurro
哈,非常感谢 - 是的,在上面我尝试使用 col2rgb 将颜色转换为 RGB,然后使用 rgb2hsv 将其从 RGB 转换为 HSV,之后我修改了第二行,我认为那是饱和度,然后使用 hsv 将其从 HSV 转换为颜色。不确定为什么这不起作用...但我会研究一下 heat.colors - 感谢您的指引! - Tom Wenseleers

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