如何在 R 中生成一些最具特色的颜色?

我正在绘制一个分类数据集,并希望使用不同的颜色来表示不同的类别。给定一个数字 n,我怎样才能得到最独特的颜色在 R 的 n数字?谢谢。

187128 次浏览

你可以使用 colorRampPalette从基地或 RColorBrewer软件包:

使用 colorRampPalette,你可以指定如下颜色:

colorRampPalette(c("red", "green"))(5)
# [1] "#FF0000" "#BF3F00" "#7F7F00" "#3FBF00" "#00FF00"

你也可以提供十六进制代码:

colorRampPalette(c("#3794bf", "#FFFFFF", "#df8640"))(5)
# [1] "#3794BF" "#9BC9DF" "#FFFFFF" "#EFC29F" "#DF8640"
# Note that the mid color is the mid value...

使用 RColorBrewer,您可以使用来自预先存在的调色板的颜色:

require(RColorBrewer)
brewer.pal(9, "Set1")
# [1] "#E41A1C" "#377EB8" "#4DAF4A" "#984EA3" "#FF7F00" "#FFFF33" "#A65628" "#F781BF"
# [9] "#999999"

查看其他可用调色板的 RColorBrewer包。希望这有所帮助。

下面是一些选择:

  1. 看一下 palette函数:

     palette(rainbow(6))     # six color rainbow
    (palette(gray(seq(0,.9,len = 25)))) #grey scale
    
  2. colorRampPalette函数:

     ##Move from blue to red in four colours
    colorRampPalette(c("blue", "red"))( 4)
    
  3. 看看 RColorBrewer包裹(和 网站)。如果你想要发散的颜色,然后在网站上选择 分歧。例如,

     library(RColorBrewer)
    brewer.pal(7, "BrBG")
    
  4. 我想要色调网站提供了很多不错的调色板。同样,只需选择所需的调色板。例如,你可以从站点获取 rgb 颜色,然后制作你自己的调色板:

     palette(c(rgb(170,93,152, maxColorValue=255),
    rgb(103,143,57, maxColorValue=255),
    rgb(196,95,46, maxColorValue=255),
    rgb(79,134,165, maxColorValue=255),
    rgb(205,71,103, maxColorValue=255),
    rgb(203,77,202, maxColorValue=255),
    rgb(115,113,206, maxColorValue=255)))
    

我加入了所有定性调色板从 RColorBrewer包。定性调色板应该提供 X 最独特的颜色每个。当然,混合他们加入到一个调色板也相似的颜色,但这是最好的,我可以得到(74种颜色)。

library(RColorBrewer)
n <- 60
qual_col_pals = brewer.pal.info[brewer.pal.info$category == 'qual',]
col_vector = unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))
pie(rep(1,n), col=sample(col_vector, n))

colour_Brewer_qual_60

另一种解决方案是: 从图形设备中提取所有 R 颜色并从中取样。我去掉了灰色的阴影,因为它们太相似了。这里有433种颜色

color = grDevices::colors()[grep('gr(a|e)y', grDevices::colors(), invert = T)]

set of 20 colours

pie(rep(1,n), col=sample(color, n))

200种颜色:

pie(rep(1,n), col=sample(color, n))

set of 200 colours

你也可以试试 randomcoloR包裹:

library(randomcoloR)
n <- 20
palette <- distinctColorPalette(n)

你可以看到,当你在饼图中可视化的时候,会选择一组高度不同的颜色(正如其他答案所建议的那样) :

pie(rep(1, n), col=palette)

enter image description here

在50种颜色的饼图中显示:

n <- 50
palette <- distinctColorPalette(n)
pie(rep(1, n), col=palette)

enter image description here

我会建议使用大调色板的外部来源。

Http://tools.medialab.sciences-po.fr/iwanthue/

有一个服务,可以根据各种参数组成任意大小的调色板

Https://graphicdesign.stackexchange.com/questions/3682/where-can-i-find-a-large-palette-set-of-contrasting-colors-for-coloring-many-d/3815

从图形设计师的角度讨论了一般性问题,并给出了许多可用调色板的例子。

要从 RGB 值组成调色板,只需要复制向量中的值,例如:

colors37 = c("#466791","#60bf37","#953ada","#4fbe6c","#ce49d3","#a7b43d","#5a51dc","#d49f36","#552095","#507f2d","#db37aa","#84b67c","#a06fda","#df462a","#5b83db","#c76c2d","#4f49a3","#82702d","#dd6bbb","#334c22","#d83979","#55baad","#dc4555","#62aad3","#8c3025","#417d61","#862977","#bba672","#403367","#da8a6d","#a79cd4","#71482c","#c689d0","#6b2940","#d593a7","#895c8b","#bd5975")

这不是 OP 问题的答案,但是值得一提的是,有一个 viridis包,它对于连续数据有很好的调色板。它们在感知上是一致的,色盲安全且对打印机友好。

要获得调色板,只需安装包并使用函数 viridis_pal()。有四个选项“ A”、“ B”、“ C”和“ D”可供选择

install.packages("viridis")
library(viridis)
viridis_pal(option = "D")(n)  # n = number of colors seeked

enter image description here

enter image description here

enter image description here

YouTube 上还有一个很棒的演讲,解释了好的彩色地图的复杂性:

Matplotlib 更好的默认色彩图 | SciPy 2015 | Nathaniel Smith and Stefan van der Walt

我发现一个网站提供了20种不同颜色的列表: https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/

col_vector<-c('#e6194b', '#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080', '#e6beff', '#9a6324', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1', '#000075', '#808080', '#ffffff', '#000000')

你可以试试!

你可以像这样生成一组颜色:

myCol = c("pink1", "violet", "mediumpurple1", "slateblue1", "purple", "purple3",
"turquoise2", "skyblue", "steelblue", "blue2", "navyblue",
"orange", "tomato", "coral2", "palevioletred", "violetred", "red2",
"springgreen2", "yellowgreen", "palegreen4",
"wheat2", "tan", "tan2", "tan3", "brown",
"grey70", "grey50", "grey30")

这些颜色尽可能清晰。对于那些相似的颜色,它们形成一个渐变,这样你就可以很容易地区分它们之间的差异。

根据我的理解,搜索不同的颜色与从单位立方体中高效搜索有关,其中立方体的3个维度是沿着红色、绿色和蓝色轴的3个向量。这可以简化为在圆柱体中搜索(HSV 类比) ,在圆柱体中修正饱和度(S)和值(V)并找到随机色调值。它在很多情况下都有效,看这里:

Https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

在 R,

get_distinct_hues <- function(ncolor,s=0.5,v=0.95,seed=40) {
golden_ratio_conjugate <- 0.618033988749895
set.seed(seed)
h <- runif(1)
H <- vector("numeric",ncolor)
for(i in seq_len(ncolor)) {
h <- (h + golden_ratio_conjugate) %% 1
H[i] <- h
}
hsv(H,s=s,v=v)
}

另一种方法,是使用 R 包“一致” Https://cran.r-project.org/web/packages/uniformly/index.html

这个简单的函数可以产生独特的颜色:

get_random_distinct_colors <- function(ncolor,seed = 100) {
require(uniformly)
set.seed(seed)
rgb_mat <- runif_in_cube(n=ncolor,d=3,O=rep(0.5,3),r=0.5)
rgb(r=rgb_mat[,1],g=rgb_mat[,2],b=rgb_mat[,3])
}

我们可以通过网格搜索想出一个更复杂的函数:

get_random_grid_colors <- function(ncolor,seed = 100) {
require(uniformly)
set.seed(seed)
ngrid <- ceiling(ncolor^(1/3))
x <- seq(0,1,length=ngrid+1)[1:ngrid]
dx <- (x[2] - x[1])/2
x <- x + dx
origins <- expand.grid(x,x,x)
nbox <- nrow(origins)
RGB <- vector("numeric",nbox)
for(i in seq_len(nbox)) {
rgb <- runif_in_cube(n=1,d=3,O=as.numeric(origins[i,]),r=dx)
RGB[i] <- rgb(rgb[1,1],rgb[1,2],rgb[1,3])
}
index <- sample(seq(1,nbox),ncolor)
RGB[index]
}

检查这些功能:

ncolor <- 20
barplot(rep(1,ncolor),col=get_distinct_hues(ncolor))          # approach 1
barplot(rep(1,ncolor),col=get_random_distinct_colors(ncolor)) # approach 2
barplot(rep(1,ncolor),col=get_random_grid_colors(ncolor))     # approach 3

然而,请注意,用人类可感知的颜色定义一个独特的调色板并不简单。以上哪种方法产生不同的颜色集尚待测试。

您可以为此目的使用 彩色的包。它只需要一些颜色的数量和一些 seedcolors。例如:

# install.packages("Polychrome")
library(Polychrome)


# create your own color palette based on `seedcolors`
P36 = createPalette(36,  c("#ff0000", "#00ff00", "#0000ff"))
swatch(P36)

您可以在 https://www.jstatsoft.org/article/view/v090c01了解更多有关此软件包的信息。