Comment générer un certain nombre de couleurs les plus distinctives dans R?


130

Je trace un ensemble de données catégoriques et je souhaite utiliser des couleurs distinctives pour représenter différentes catégories. Étant donné un nombre n, comment puis-je obtenir le nnombre de couleurs les plus distinctives dans R? Merci.



Réponses:


108

J'ai rejoint toutes les palettes qualitatives du RColorBrewerpackage. Les palettes qualitatives sont censées fournir chacune X couleurs les plus distinctives. Bien sûr, les mélanger dans une palette de couleurs similaires, mais c'est le meilleur que je puisse obtenir (74 couleurs).

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

Une autre solution est: prenez toutes les couleurs R des appareils graphiques et échantillonnez-les. J'ai supprimé les nuances de gris car elles sont trop similaires. Cela donne 433 couleurs

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

ensemble de 20 couleurs

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

avec 200 couleurs n = 200:

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

ensemble de 200 couleurs


Est-il possible de convertir les codes hexadécimaux en colnoms de couleurs correspondants?
Prradep

@Prradep que colvoulez-vous dire? les colorpériphériques graphiques ont des noms. Si vous voulez dire en général, tous les codes hexadécimaux n'ont pas de noms de couleurs correspondants (il n'y a que 433 couleurs grDevicesmais beaucoup plus de codes hexadécimaux)
JelenaČuklina

Je mentionne à propos col=sample(col_vector, n)du RColorBrewerpackage dans votre extrait de code. Par exemple, Comment trouver les noms de couleur #B3E2CD, #E78AC3, #B3DE69disponibles à partir de sample(col_vector,3). Sinon, comment trouver tous les codes hexadécimaux donnés par brewer.palfonction avec leurs noms de couleur.
Prradep

2
@Prradep, car les RColorBrewerpalettes ne sont pas dérivées de grDevicescouleurs, qui ont des noms mappés, mais sont juste des codes hexadécimaux, à ma connaissance, vous ne pouvez pas faire cela avec des RColorBrewerpalettes, même qualitatives.
JelenaČuklina

1
@ytu alors les couleurs ne se distinguent pas. Si c'est absolument nécessaire, je suggérerais de rechercher la "création de dégradés" dans R puis d'utiliser un échantillonnage aléatoire des couleurs. Mais la cartographie des couleurs aux facteurs ne fonctionnera pas, la perception humaine peut gérer peut-être 20 à 40 couleurs, le reste n'est pas si différent.
JelenaČuklina

70

Voici quelques options:

  1. Jetez un œil à la palettefonction:

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

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
  3. Regardez le colorBrewerpackage (et le site Web ). Si vous voulez des couleurs divergentes, sélectionnez divergentes sur le site. Par exemple,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
  4. Le site Web I want hue propose de nombreuses palettes intéressantes. Encore une fois, sélectionnez simplement la palette dont vous avez besoin. Par exemple, vous pouvez obtenir les couleurs RVB du site et créer votre propre palette:

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

Merci pour votre réponse. Il génère des couleurs, mais certaines peu distinctives les unes des autres. J'aurais peut-être dû insister davantage là-dessus dans mes questions.
RNA

1
@RNAer J'ai mis à jour ma réponse. Vous pouvez utiliser les suggestions 3 et 4 pour obtenir des palettes divergentes .
csgillespie

1
I want hueest un site Web génial. C'est exactement ce que je veux. Étant donné un nombre, comment générer une palette du nombre de couleurs. mais pouvons-nous le faire en R automatiquement?
RNA

C'est génial. Cependant, il y a beaucoup de machines derrière ce site Web. Je ne pense pas que ce sera anodin à réimplémenter. Ce serait bien d' i want hueavoir une API qui lui permette d'être automatiquement interrogée (peut-être que c'est le cas - je n'ai pas passé longtemps à chercher)
Ben Bolker

8
@BenBolker - J'ai fait l'essentiel d'une version R de i want hue, ici . L'efficacité pourrait être améliorée (par exemple en enregistrant des échantillons de couleur en tant qu'objets de données), mais l'idée générale est là. (Charger avec devtools::source_gist('45b49da5e260a9fc1cd7'))
jbaums

36

Vous pouvez également essayer le randomcoloRpackage :

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

Vous pouvez voir qu'un ensemble de couleurs très distinctes est choisi lors de la visualisation dans un graphique à secteurs (comme suggéré par d'autres réponses ici):

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

entrez la description de l'image ici

Représenté dans un camembert avec 50 couleurs:

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

entrez la description de l'image ici


3
Merci. J'ai dû l'utiliser unname(distinctColorPalette(n))pour que cela fonctionne avec ggplot. Je suppose que ggplot a besoin d'un vecteur sans nom. col_vector <- unname(distinctColorPalette(n))et puis... + scale_color_manual(values=col_vector) ...
Gaurav

19

Ce n'est pas une réponse à la question d'OP, mais il convient de mentionner qu'il existe un viridispackage qui a de bonnes palettes de couleurs pour les données séquentielles. Ils sont perceptuellement uniformes, sûrs pour les daltoniens et faciles à imprimer.

Pour obtenir la palette, installez simplement le package et utilisez la fonction viridis_pal(). Il y a quatre options "A", "B", "C" et "D" à choisir

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

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

Il y a aussi une excellente présentation expliquant la complexité des bonnes couleurs sur YouTube:

Une meilleure palette de couleurs par défaut pour Matplotlib | SciPy 2015 | Nathaniel Smith et Stéfan van der Walt


17
Ce n'est pas si approprié pour les couleurs distinctives.
Christopher John

13

Vous pouvez utiliser à colorRampPalettepartir de la base ou du RColorBrewerpackage:

Avec colorRampPalette, vous pouvez spécifier les couleurs comme suit:

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

Vous pouvez également fournir des codes hexadécimaux:

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

Avec RColorBrewervous pouvez utiliser des couleurs de palettes préexistantes:

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

Regarder RColorBrewer package pour d'autres palettes disponibles. J'espère que cela t'aides.


1
Merci. J'aime la dernière option brewer.pal. mais il est limité à 9 couleurs. J'ai en fait plus de 9 catégories. Les premières alternatives génèrent un dégradé de couleurs, qui n'est pas aussi distinctif que je le souhaite.
RNA

2
vous ne pourrez pas choisir de nombreuses couleurs «distinctes». Vous pouvez en obtenir un maximum de 12, je suppose. Vous devriez consulter colorbrewer2.org et obtenir les couleurs (il y a 1 palette de 12 couleurs si j'ai raison).
Arun

La recherche de plus de 12 couleurs distinctives sera difficile - je pense qu'il y a une discussion à ce sujet sur la page
colorbrewer

c'est bien, tant que ce sont les couleurs les plus distinctives disponibles, même si elles deviennent moins distinctives lorsque le nombre augmente.
RNA

3
Si votre problème concerne des couleurs similaires côte à côte lorsqu'elles sont affectées à des catégories adjacentes (comme le fera la palette arc-en-ciel), vous pouvez simplement randomiser la sortie arc-en-ciel avec quelque chose comme: arc-en-ciel (n = 10) [sample (10)]
David Roberts

11

Je recommanderais d'utiliser une source externe pour les grandes palettes de couleurs.

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

dispose d'un service pour composer n'importe quelle taille de palette selon divers paramètres et

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

traite du problème générique du point de vue des graphistes et donne de nombreux exemples de palettes utilisables.

Pour constituer une palette à partir de valeurs RVB, il vous suffit de copier les valeurs dans un vecteur comme par exemple:

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

J'ai trouvé un site internet proposant une liste de 20 couleurs distinctives: 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')

Vous pouvez essayer!


1
Cela ne répond pas vraiment à la question, qui consiste à générer n des couleurs distinctives, pas un ensemble de couleurs définies. Essayez de mettre à jour votre réponse
Michal

1

Vous pouvez générer un ensemble de couleurs comme celui-ci:

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

Ces couleurs sont aussi distinctes que possible. Pour ces couleurs similaires, elles forment un dégradé afin que vous puissiez facilement distinguer les différences entre elles.


0

Dans ma compréhension, la recherche de couleurs distinctives est liée à une recherche efficace à partir d'un cube unitaire, où 3 dimensions du cube sont trois vecteurs le long des axes rouge, vert et bleu. Cela peut être simplifié pour rechercher dans un cylindre (analogie HSV), où vous fixez la saturation (S) et la valeur (V) et trouvez des valeurs de teinte aléatoires. Cela fonctionne dans de nombreux cas, et voyez ceci ici:

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

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

Une autre manière consiste à utiliser le package R "uniformément" https://cran.r-project.org/web/packages/uniformly/index.html

et cette fonction simple peut générer des couleurs distinctives:

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

On peut penser à une fonction un peu plus impliquée par la recherche de grille:

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

vérifiez cette fonction en:

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

Cependant, notez que définir une palette distincte avec des couleurs perceptibles par l'homme n'est pas simple. Laquelle des approches ci-dessus génère un ensemble de couleurs diversifié doit encore être testée.


0

Vous pouvez utiliser le package Polychrome à cet effet. Cela nécessite juste le nombre de couleurs et quelques-unes seedcolors. Par exemple:

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

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

Vous pouvez en savoir plus sur ce package à l' adresse https://www.jstatsoft.org/article/view/v090c01 .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.