Como gerar um número de cores mais distintas no R?


Respostas:


108

Juntei todas as paletas qualitativas do RColorBrewerpacote. As paletas qualitativas devem fornecer X cores mais distintas cada. Obviamente, misturá-los junta-se a uma paleta de cores semelhantes, mas é o melhor que consigo (74 cores).

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

Outra solução é: pegue todas as cores R de dispositivos gráficos e faça uma amostra deles. Eu removi tons de cinza, pois são muito semelhantes. Isso dá 433 cores

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

conjunto de 20 cores

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

com 200 cores n = 200:

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

conjunto de 200 cores


Existe a possibilidade de converter os códigos hexadecimais em colnomes de cores correspondentes?
— Prradep

@Prradep, o que colvocê quer dizer? o colorde dispositivos gráficos tem nomes. Se você quer dizer em, nem todos código geral hex têm nomes de cores correspondentes (há apenas 433 cores em grDevicesmas muitos códigos mais hex)
— JelenaČuklina

Eu estou mencionando sobre col=sample(col_vector, n)o RColorBrewerpacote no seu trecho de código. Por exemplo, Como encontrar os nomes das cores #B3E2CD, #E78AC3, #B3DE69disponíveis em sample(col_vector,3). Como alternativa, Como encontrar todos os códigos hexadecimais fornecidos pela brewer.palfunção com seus nomes de cores.
— Prradep

2
@Prradep, como RColorBrewerpaletas não são derivadas de grDevicescores, que têm nomes mapeados, mas são apenas códigos hexadecimais, que eu saiba, você não pode fazer isso com RColorBrewerpaletas, mesmo qualitativas.
— JelenaČuklina

1
@ytu então as cores não são distinguíveis. Se for absolutamente necessário, sugiro procurar "criação de gradiente" em R e, em seguida, usar amostragem aleatória de cores. Mas o mapeamento de cores para fatores não funcionará, a percepção humana pode lidar com talvez de 20 a 40 cores, o resto não é muito diferente.
— JelenaČuklina 03/07/19

70

Aqui estão algumas opções:

  1. Dê uma olhada na palettefunção:

     palette(rainbow(6))     # six color rainbow
     (palette(gray(seq(0,.9,len = 25)))) #grey scale
  2. E a colorRampPalettefunção:

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
  3. Veja o colorBrewerpacote (e o site ). Se você quiser cores divergentes, selecione divergências no site. Por exemplo,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
  4. O site Eu quero o matiz oferece muitas paletas agradáveis. Mais uma vez, basta selecionar a paleta que você precisa. Por exemplo, você pode obter as cores rgb no site e criar sua própria paleta:

     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)))

obrigado pela sua resposta. Ele gera cores, mas algumas não são muito distintas entre si. talvez eu devesse ter enfatizado mais isso nas minhas perguntas.
— RNA

1
@RNAer Atualizei minha resposta. Você pode usar as sugestões 3 e 4 para obter paletas divergentes .
— precisa saber é o seguinte

1
I want hueé um site incrível. É exatamente isso que eu quero. Dado um número, como gerar uma paleta do número de cores. mas podemos fazer isso no R automaticamente?
— RNA

Isso é incrível. No entanto, há muitas máquinas por trás desse site. Não acho que seja trivial reimplementar. Seria bom se i want huetivesse uma API que permitisse que ela fosse automaticamente consultada (talvez exista - eu não gastei muito tempo procurando) #
— 11553 Ben Bolker Ben Bolker

8
@BenBolker - Eu fiz uma essência para uma versão R i want hue, aqui . A eficiência pode ser melhorada (por exemplo, salvando amostras de cores como objetos de dados), mas a idéia geral está lá. (Load with devtools::source_gist('45b49da5e260a9fc1cd7'))
— jbaums

36

Você também pode experimentar o randomcoloRpacote :

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

Você pode ver que um conjunto de cores altamente distintas é escolhido ao visualizar em um gráfico de pizza (conforme sugerido por outras respostas aqui):

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

insira a descrição da imagem aqui

Mostrado em um gráfico de pizza com 50 cores:

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

insira a descrição da imagem aqui


3
Obrigado. Eu tive que usar unname(distinctColorPalette(n))para fazer isso funcionar com o ggplot. Eu acho que o ggplot precisa de um vetor sem nome. col_vector <- unname(distinctColorPalette(n))e então... + scale_color_manual(values=col_vector) ...
— Gaurav

19

Não é uma resposta à pergunta do OP, mas vale a pena mencionar que existe o viridispacote que possui boas paletas de cores para dados sequenciais. Eles são perceptualmente uniformes, daltônicos, seguros e de impressão.

Para chegar a paleta, basta instalar o pacote e usar a função viridis_pal(). Existem quatro opções "A", "B", "C" e "D" para escolher

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

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Há também uma excelente conversa explicando a complexidade de bons mapas de cores no YouTube:

Um melhor mapa de cores padrão para o Matplotlib | SciPy 2015 | Nathaniel Smith e Stéfan van der Walt


17
Isso não é adequado para cores distintas.
— Christopher John

13

Você pode usar colorRampPaletteda base ou do RColorBrewerpacote:

Com colorRampPalette, você pode especificar cores da seguinte maneira:

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

Como alternativa, você também pode fornecer códigos hexadecimais:

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

Com RColorBrewervocê pode usar cores de paletas pré-existentes:

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

Veja o RColorBrewerpacote para outras paletas disponíveis. Espero que isto ajude.


1
Obrigado. Eu gosto da última opção brewer.pal. mas é limitado a 9 cores. Na verdade, tenho mais de 9 categorias. As primeiras alternativas geram cores de gradiente, que não são tão distintas quanto eu quero.
— RNA

2
você não poderá escolher muitas cores "distintas". Você pode obter no máximo 12, suponho. Você deve verificar o colorbrewer2.org e obter as cores (há uma paleta de 12 cores, se eu estiver certo).
— Arun

Procurando por mais de 12 colouts distintivas será difícil - Eu acho que há discussão sobre isso na página ColorBrewer
— alexwhan

isso é bom, desde que sejam as cores "mais" distintivas disponíveis, até elas se tornam menos distintas quando o número aumenta.
— RNA

3
Se o seu problema for de cores semelhantes lado a lado quando atribuído a categorias adjacentes (como a paleta do arco-íris fará), você poderá simplesmente aleatoriamente a saída do arco-íris com algo como: rainbow (n = 10) [sample (10)]
— David Roberts

11

Eu recomendaria usar uma fonte externa para grandes paletas de cores.

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

possui um serviço para compor qualquer tamanho de paleta de acordo com vários parâmetros e

/graphicdesign/3682/where-can-i-find-a-large-palette-set-of-contrasting-colors-for-coloring-many-d/3815

discute o problema genérico da perspectiva de designers gráficos e fornece muitos exemplos de paletas utilizáveis.

Para incluir uma paleta de valores RGB, basta copiar os valores em um vetor, como por exemplo:

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")

3

Encontrei um site que oferece uma lista de 20 cores distintas: 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')

Você pode tentar!


1
Isso realmente não responde à pergunta, que é gerar n cores distintas, não um conjunto de cores definidas. Tente atualizar sua resposta
— Michal

1

Você pode gerar um conjunto de cores como este:

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")

Essas cores são tão distintas quanto possível. Para essas cores semelhantes, elas formam um gradiente para que você possa distinguir facilmente as diferenças entre elas.


0

No meu entendimento, a busca de cores distintas está relacionada à busca eficiente de um cubo unitário, em que três dimensões do cubo são três vetores ao longo dos eixos vermelho, verde e azul. Isso pode ser simplificado para procurar em um cilindro (analogia HSV), onde você fixa Saturação (S) e Valor (V) e encontra valores aleatórios de Matiz. Funciona em muitos casos, e veja isso aqui:

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

Em 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)
}

Uma maneira alternativa é usar o pacote R "uniformemente" https://cran.r-project.org/web/packages/uniformly/index.html

e essa função simples pode gerar cores distintas:

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])
}

Pode-se pensar em uma função um pouco mais envolvida pela pesquisa em grade:

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]
} 

verifique estas funções:

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

No entanto, observe que definir uma paleta distinta com cores perceptíveis em humanos não é simples. Qual das abordagens acima gera diversas cores ainda não foi testada.


0

Você pode usar o pacote Polychrome para esse fim. Requer apenas o número de cores e algumas seedcolors. Por exemplo:

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

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

Você pode aprender mais sobre este pacote em https://www.jstatsoft.org/article/view/v090c01 .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.