Come generare un numero di colori più distintivi in ​​R?


Risposte:


108

Ho unito tutte le tavolozze qualitative dal RColorBrewerpacchetto. Le tavolozze qualitative dovrebbero fornire X colori più distintivi ciascuno. Naturalmente, mescolandoli si unisce in una palette anche colori simili, ma è il migliore che posso ottenere (74 colori).

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

Un'altra soluzione è: prendere tutti i colori R dai dispositivi grafici e campionarli. Ho rimosso le sfumature di grigio in quanto troppo simili. Questo dà 433 colori

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

set di 20 colori

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

con 200 colori n = 200:

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

set di 200 colori


Esiste la possibilità di convertire i codici esadecimali nei colnomi dei colori corrispondenti?
Prradep,

@Prradep che colvuoi dire? il colorda dispositivi grafici ha nomi. Se intendi in generale, non tutti i codici esadecimali hanno nomi di colore corrispondenti (ci sono solo 433 colori grDevicesma molti altri codici esadecimali)
JelenaČuklina

Sto citando col=sample(col_vector, n)dal RColorBrewerpacchetto nel tuo frammento di codice. Ad esempio, come trovare i nomi dei colori #B3E2CD, #E78AC3, #B3DE69disponibili da sample(col_vector,3). In alternativa, come trovare tutti i codici esadecimali dati dalla brewer.palfunzione con i loro nomi di colore.
Prradep,

2
@Prradep, poiché le RColorBrewertavolozze non derivano da grDevicescolori, che hanno nomi mappati, ma sono solo codici esadecimali, per quanto ne sappia, non puoi farlo con le RColorBrewertavolozze, anche con quelle qualitative.
JelenaČuklina,

1
@ytu quindi i colori non sono distinguibili. Se assolutamente necessario, suggerirei di cercare la "creazione del gradiente" in R e di utilizzare il campionamento casuale dei colori. Ma la mappatura dai colori ai fattori non funzionerà, la percezione umana può gestire forse 20 - 40 colori, il resto non è molto diverso.
JelenaČuklina,

70

Ecco alcune opzioni:

  1. Dai un'occhiata alla palettefunzione:

     palette(rainbow(6))     # six color rainbow
     (palette(gray(seq(0,.9,len = 25)))) #grey scale
  2. E la colorRampPalettefunzione:

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
  3. Guarda il colorBrewerpacchetto (e il sito Web ). Se vuoi colori divergenti, seleziona divergenti sul sito. Per esempio,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
  4. Il sito web I want hue offre molte belle tavolozze. Ancora una volta, basta selezionare la tavolozza di cui hai bisogno. Ad esempio, è possibile ottenere i colori RGB dal sito e creare la propria tavolozza:

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

grazie per la tua risposta. Genera colori, ma alcuni non sono molto distintivi tra loro. forse avrei dovuto porre maggiormente l'accento su questo nelle mie domande.
RNA

1
@RNAer Ho aggiornato la mia risposta. È possibile utilizzare i suggerimenti 3 e 4 per ottenere tavolozze divergenti .
csgillespie,

1
I want hueè un sito fantastico. Questo è esattamente quello che voglio. Dato un numero, come generare una tavolozza del numero di colori. ma possiamo farlo automaticamente in R?
RNA

È fantastico. Tuttavia, ci sono molti macchinari dietro quel sito web. Non credo che sarà banale reimplementare. Sarebbe bello se i want hueavesse un'API che gli permettesse di essere interrogato automaticamente (forse lo fa - non ho trascorso molto tempo a cercare)
Ben Bolker

8
@BenBolker - Ho fatto un'idea per una versione R di i want hue, qui . L'efficienza potrebbe essere migliorata (ad esempio salvando campioni di colore come oggetti dati), ma l'idea generale è lì. (Carica con devtools::source_gist('45b49da5e260a9fc1cd7'))
jbaums,

36

Puoi anche provare il randomcoloRpacchetto :

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

Puoi vedere che un set di colori altamente distinti viene scelto quando visualizzi in un grafico a torta (come suggerito da altre risposte qui):

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

inserisci qui la descrizione dell'immagine

Mostrato in un grafico a torta con 50 colori:

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

inserisci qui la descrizione dell'immagine


3
Grazie. Ho dovuto usarlo unname(distinctColorPalette(n))per far funzionare questo con ggplot. Immagino che ggplot abbia bisogno di un vettore senza nome. col_vector <- unname(distinctColorPalette(n))e poi... + scale_color_manual(values=col_vector) ...
Gaurav,

19

Non è una risposta alla domanda di OP, ma vale la pena ricordare che esiste un viridispacchetto che ha buone tavolozze di colori per dati sequenziali. Sono percettivamente uniformi, daltonici sicuri e facili da stampare.

Per ottenere la tavolozza, è sufficiente installare il pacchetto e utilizzare la funzione viridis_pal(). Sono disponibili quattro opzioni "A", "B", "C" e "D"

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

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

C'è anche un eccellente discorso che spiega la complessità delle buone mappe dei colori su YouTube:

Una migliore mappa dei colori predefinita per Matplotlib | SciPy 2015 | Nathaniel Smith e Stéfan van der Walt


17
Questo non è così adatto per i colori distintivi.
Christopher John,

13

Puoi usare colorRampPalettedalla base o dal RColorBrewerpacchetto:

Con colorRampPalette, è possibile specificare i colori come segue:

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

In alternativa puoi fornire anche codici esadecimali:

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

Con RColorBrewerte puoi usare i colori delle tavolozze preesistenti:

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

Guarda il RColorBrewerpacchetto per altre tavolozze disponibili. Spero che questo ti aiuti.


1
Grazie. Mi piace l'ultima opzione brewer.pal. ma è limitato a un massimo di 9 colori. In realtà ho più di 9 categorie. Le prime alternative generano una sfumatura di colori, che non è così distintiva come voglio.
RNA

2
non sarai in grado di scegliere molti colori "distinti". Puoi ottenere un massimo di 12 suppongo. Dovresti dare un'occhiata a colorbrewer2.org e ottenere i colori (c'è una tavolozza di 12 colori se ho ragione).
Arun,

Cercare più di 12 colori distintivi sarà difficile - penso che ci sia discussione al riguardo sulla pagina del colorbrewer
alexwhan

va bene, purché siano i "più" colori distintivi disponibili, anche se diventano sempre più distintivi quando il numero aumenta.
RNA

3
Se il tuo problema è colori simili affiancati quando assegnati a categorie adiacenti (come farà la tavolozza arcobaleno), potresti semplicemente randomizzare l'output arcobaleno con qualcosa del tipo: arcobaleno (n = 10) [campione (10)]
David Roberts,

11

Consiglierei di utilizzare una fonte esterna per grandi tavolozze di colori.

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

ha un servizio per comporre qualsiasi dimensione della tavolozza in base a vari parametri e

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

discute il problema generico dal punto di vista dei grafici e fornisce molti esempi di tavolozze utilizzabili.

Per comprendere una tavolozza dai valori RGB non devi fare altro che copiare i valori in un vettore come ad esempio:

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

Ho trovato un sito Web che offre un elenco di 20 colori distintivi: 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')

Puoi fare una prova!


1
Questo in realtà non risponde alla domanda, che riguarda la generazione di n colori distintivi, non un insieme di colori definiti. Prova ad aggiornare la tua risposta
Michal,

1

Puoi generare un set di colori come questo:

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

Questi colori sono il più distinti possibile. Per quei colori simili, formano un gradiente in modo da poter facilmente distinguere le differenze tra loro.


0

Nella mia comprensione, la ricerca di colori distintivi è correlata alla ricerca efficiente da un cubo unitario, in cui 3 dimensioni del cubo sono tre vettori lungo gli assi rosso, verde e blu. Questo può essere semplificato per la ricerca in un cilindro (analogia HSV), dove si fissano Saturazione (S) e Valore (V) e si trovano valori di tonalità casuali. Funziona in molti casi, e vedi qui:

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

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

Un modo alternativo è usare il pacchetto R "uniformemente" https://cran.r-project.org/web/packages/uniformly/index.html

e questa semplice funzione può generare colori distintivi:

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

Si può pensare alla funzione un po 'più coinvolta dalla ricerca della griglia:

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

controlla queste funzioni:

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

Tuttavia, notare che definire una palette distinta con colori percepibili dall'uomo non è semplice. Quale approccio sopra citato genera diversi set di colori deve ancora essere testato.


0

A tale scopo è possibile utilizzare il pacchetto Polychrome . Richiede solo il numero di colori e alcuni seedcolors. Per esempio:

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

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

Puoi saperne di più su questo pacchetto su https://www.jstatsoft.org/article/view/v090c01 .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.