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

JelenaČuklina
fonte
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)))
csgillespie
fonte
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

Megatron
fonte
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

Gordon Schücker
fonte
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.

Uma corrida
fonte
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")
romano
fonte
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!

Minstein
fonte
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.

Phoenix Mu
fonte
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.

bJust
fonte
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 .

Jot eN
fonte