什么是R中不同颜色的“好”调色板?(或者:翡翠和岩浆能结合在一起吗?)

2024-10-17 00:24:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有兴趣有一个“好”的发散色托盘。很明显,我们可以只使用红色、白色和蓝色:

img <- function(obj, nam) {
  image(1:length(obj), 1, as.matrix(1:length(obj)), col=obj, 
        main = nam, ylab = "", xaxt = "n", yaxt = "n",  bty = "n")
}
rwb <- colorRampPalette(colors = c("red", "white", "blue"))
img(rwb(100), "red-white-blue")

enter image description here

自从我最近爱上了viridis color palettes,我就希望把绿蜘蛛和岩浆结合起来,形成这样不同的颜色(当然,色盲的人只会看到颜色的绝对值,但有时也没问题)。

当我尝试将viridis和magma结合起来时,我发现它们不会在同一个地方“结束”(或“开始”),所以我得到了类似的结果(我使用R,但对于python用户来说可能是相同的):

library(viridis)
img(c(rev(viridis(100, begin = 0)), magma(100, begin = 0)), "magma-viridis")

enter image description here

我们可以看到,当接近零时,绿柱石是紫色的,而岩浆是黑色的。我想让他们两个在(或多或少)相同的位置开始,所以我尝试使用0.3作为起点:

img(c(rev(viridis(100, begin = 0.3)), magma(100, begin = 0.3)), "-viridis-magma(0.3)")

enter image description here

这确实更好,但我想知道是否有更好的解决办法。

(我也在“标记”python用户,因为viridis最初来自matplotlib,所以使用它的人可能知道这样的解决方案)

谢谢!


Tags: 用户objimg颜色revblueredlength
3条回答

我觉得Kenneth Moreland's proposal很有用。 它是在Rgnuplot包中实现的(install.packages("Rgnuplot")已经足够了,您不需要安装GNU plot)。要像使用常用颜色贴图一样使用它,需要按如下方式转换:

cool_warm <- function(n) {
  colormap <- Rgnuplot:::GpdivergingColormap(seq(0,1,length.out=n),
                                             rgb1 = colorspace::sRGB( 0.230, 0.299, 0.754),
                                             rgb2 = colorspace::sRGB( 0.706, 0.016, 0.150),
                                             outColorspace = "sRGB")
  colormap[colormap>1] <- 1 # sometimes values are slightly larger than 1
  colormap <- grDevices::rgb(colormap[,1], colormap[,2], colormap[,3])
  colormap
}

img(red_blue_diverging_colormap(500), "Cool-warm, (Moreland 2009)")

cool-warm colormap 与插入的RColorBrewer“RdBu”相比,它的实际效果是这样的:comparison

RColorBrewer为=<;13种颜色提供漂亮的调色板。例如,调色板BrBG显示从棕色到绿色的不同颜色。

library(RColorBrewer)
display.brewer.pal(11, "BrBG")

enter image description here

通过在中间点颜色之间创建调色板,可以将其扩展为信息量较少的调色板。

brbg <- brewer.pal(11, "BrBG")
cols <- c(colorRampPalette(c(brbg[1], brbg[6]))(51), 
    colorRampPalette(c(brbg[6], brbg[11]))(51)[-1])

enter image description here

类似地,使用您选择的viridismagma调色板,您可以尝试找到它们之间的相似性。这可能是一个点,在这里可以背对背地连接调色板。

select.col <- function(cols1, cols2){
    x <- col2rgb(cols1)
    y <- col2rgb(cols2)
    sim <- which.min(colSums(abs(x[,ncol(x)] - y)))
    message(paste("Your palette will be", sim, "colors shorter."))
    cols.x <- apply(x, 2, function(temp) rgb(t(temp)/255))
    cols.y <- apply(y[,sim:ncol(y)], 2, function(temp) rgb(t(temp)/255))
    return(c(cols.x,cols.y))
}

img(select.col(rev(viridis(100,0)),magma(100,0)), "")
# Your palette will be 16 colors shorter.

Palette

已经有一些好的和有用的建议,但让我补充几点:

  1. viridis和magma调色板是具有多种颜色的顺序调色板。因此,沿着比例你从非常浅的颜色增加到相当深的颜色。同时,色彩增加,色调从黄色变为蓝色(通过绿色或通过红色)。
  2. 可以通过组合两个顺序调色板来创建发散调色板。通常,你把它们加入浅色,然后让它们分岔成不同的深色。
  3. 通常,一个使用单一色调的顺序调色板,从一个中性浅灰色发散到两个不同的深色。尽管调色板的不同“臂”在亮度(明暗)和色度(色彩)方面是平衡的,但人们还是应该注意。

因此,岩浆和绿柱石的结合效果并不好。你可以让它们从一个类似的黄色发散,但你会发散到类似的蓝色。同样,随着颜色的变化,判断你在调色板的哪一个手臂上会变得更加困难。

正如其他人提到的,ColorBrewer.org提供了良好的分色调色板。Moreland的方法也很有用。另一个通用的解决方案是colorspace包中的diverging_hcl()函数。在https://arxiv.org/abs/1903.06490(即将在JSS中发布)的随附论文中,描述了构造原理,以及基于HCL的一般策略如何近似ColorBrewer.org、CARTO等中的许多调色板。 (之前的参考文献包括我们在CSDA的http://dx.doi.org/10.1016/j.csda.2008.11.033上的初步工作,以及针对气象学的进一步建议,但在BAMS的http://dx.doi.org/10.1175/BAMS-D-13-00155.1上的一篇论文中可以应用。)

我们在HCL空间(色调-色度-亮度)中的解决方案的优点是,您可以相对容易地解释坐标。它确实需要一些实践,但不像其他解决方案那样不透明。此外,我们还提供了一个GUI hclwizard()(见下文),帮助理解不同坐标的重要性。

只要两种颜色(参数h)、最大色度(c)和最小/最大亮度(l)被适当地选择,问题和其他答案中的大多数调色板都可以通过diverging_hcl()非常接近地匹配。此外,可能需要调整power参数,该参数分别控制色度和亮度增加的速度。通常,色度的增加比较快(power[1] < 1),而亮度的增加比较慢(power[2] > 1)。

例如,Moreland的“cool warm”调色板使用蓝色(h = 250)和红色(h = 10)色调,但亮度对比度相对较小(l = 37l = 88):

coolwarm_hcl <- colorspace::diverging_hcl(11,
  h = c(250, 10), c = 100, l = c(37, 88), power = c(0.7, 1.7))

看起来非常相似(见下文):

coolwarm <- Rgnuplot:::GpdivergingColormap(seq(0, 1, length.out = 11),
  rgb1 = colorspace::sRGB( 0.230, 0.299, 0.754),
  rgb2 = colorspace::sRGB( 0.706, 0.016, 0.150),
  outColorspace = "sRGB")
coolwarm[coolwarm > 1] <- 1
coolwarm <- rgb(coolwarm[, 1], coolwarm[, 2], coolwarm[, 3])

相比之下,ColorBrewer.org的BrBG调色板亮度对比度要高得多(l = 20l = 95):

brbg <- rev(RColorBrewer::brewer.pal(11, "BrBG"))
brbg_hcl <- colorspace::diverging_hcl(11,
  h = c(180, 50), c = 80, l = c(20, 95), power = c(0.7, 1.3))

下面将结果调色板与原始调色板下面基于HCL的版本进行比较。你看,它们不一样,但很接近。在右边,我还将绿脓杆菌和血浆与基于盐酸的调色板进行了匹配。

palettes

你是喜欢冷暖色调还是BrBG色调可能取决于你的个人品味,但更重要的是,你想在你的视觉效果中展现什么。如果偏差的符号最为重要,那么冷暖条件下的低亮度对比度将更为有用。如果您想显示(极端)偏差的大小,高亮度对比度将更有用。以上的论文提供了更为实际的指导。

上图的其余复制代码是:

viridis <- viridis::viridis(11)
viridis_hcl <- colorspace::sequential_hcl(11,
  h = c(300, 75), c = c(35, 95), l = c(15, 90), power = c(0.8, 1.2))

plasma <- viridis::plasma(11)
plasma_hcl <- colorspace::sequential_hcl(11,
  h = c(-100, 100), c = c(60, 100), l = c(15, 95), power = c(2, 0.9))

pal <- function(col, border = "transparent") {
  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)
}

par(mar = rep(0, 4), mfrow = c(4, 2))
pal(coolwarm)
pal(viridis)
pal(coolwarm_hcl)
pal(viridis_hcl)
pal(brbg)
pal(plasma)
pal(brbg_hcl)
pal(plasma_hcl)

更新:这些来自其他工具(ColorBrewer.org、viridis、scico、CARTO,…)的基于HCL的近似颜色现在也可以作为colorspace包和基本grDevices包(从3.6.0开始)中的hcl.colors()函数中的命名调色板使用。因此,你现在可以也可以简单地说:

colorspace::sequential_hcl(11, "viridis")
grDevices::hcl.colors(11, "viridis")

最后,您可以在闪亮的应用程序中交互探索我们建议的颜色: http://hclwizard.org:64230/hclwizard/。对于R的用户,您还可以在本地计算机上启动shiny应用程序(运行速度比我们的服务器快一些),或者运行Tcl/Tk版本的应用程序(甚至更快):

colorspace::hclwizard(gui = "shiny")
colorspace::hclwizard(gui = "tcltk")

如果您想了解调色板在RGB和HCL坐标系中的路径,那么colorspace::specplot()非常有用。请参见示例colorspace::specplot(coolwarm)

相关问题 更多 >