¿Cómo generar una serie de colores más distintivos en R?


Respuestas:


108

Me uní a todas las paletas cualitativas del RColorBrewerpaquete. Se supone que las paletas cualitativas proporcionan X colores más distintivos cada una. Por supuesto, mezclarlos se une en una paleta de colores también similares, pero eso es lo mejor que puedo obtener (74 colores).

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

Otra solución es: tomar todos los colores R de los dispositivos gráficos y tomar muestras de ellos. Eliminé tonos de gris ya que son demasiado similares. Esto da 433 colores.

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

conjunto de 20 colores

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

con 200 colores n = 200:

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

conjunto de 200 colores


¿Existe la posibilidad de convertir los códigos hexadecimales en los colnombres de color correspondientes?
Prradep

@Prradep, col¿a qué te refieres? el colorde los dispositivos gráficos tiene nombres. Si quiere decir en general, no todos los códigos hexadecimales tienen nombres de color correspondientes (solo hay 433 colores en grDevicesmuchos más códigos hexadecimales)
JelenaČuklina

Menciono sobre col=sample(col_vector, n)el RColorBrewerpaquete en su fragmento de código. Por ejemplo, Cómo encontrar los nombres de color #B3E2CD, #E78AC3, #B3DE69disponibles en sample(col_vector,3). Alternativamente, Cómo encontrar todos los códigos hexadecimales dados por brewer.palfunción con sus nombres de color.
Prradep

2
@Prradep, ya que las RColorBrewerpaletas no se derivan de grDevicescolores, que tienen nombres asignados, sino que son solo códigos hexadecimales, que yo sepa, no puede hacer esto con RColorBrewerpaletas, incluso las cualitativas.
JelenaČuklina

1
@ytu entonces los colores no son distinguibles. Si es absolutamente necesario, sugeriría buscar "creación de gradiente" en R y luego usar muestreo aleatorio de colores. Pero el mapeo de colores a factores no funcionará, la percepción humana puede manejar entre 20 y 40 colores, el resto no es muy diferente.
JelenaČuklina

70

Aquí hay algunas opciones:

  1. Echa un vistazo a la palettefunción:

     palette(rainbow(6))     # six color rainbow
     (palette(gray(seq(0,.9,len = 25)))) #grey scale
  2. Y la colorRampPalettefunción:

     ##Move from blue to red in four colours
     colorRampPalette(c("blue", "red"))( 4) 
  3. Mira el colorBrewerpaquete (y el sitio web ). Si desea colores divergentes, seleccione divergentes en el sitio. Por ejemplo,

     library(colorBrewer)
     brewer.pal(7, "BrBG")
  4. El sitio web I want hue ofrece muchas paletas bonitas. Nuevamente, solo seleccione la paleta que necesita. Por ejemplo, puede obtener los colores rgb del sitio y hacer su propia 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)))

gracias por tu respuesta. Genera colores, pero algunos no muy distintivos entre sí. quizás debería haber enfatizado más sobre eso en mis preguntas.
ARN

1
@RNAer He actualizado mi respuesta. Puede usar las sugerencias 3 y 4 para obtener paletas divergentes .
csgillespie

1
I want hueEs un sitio web increíble. Esto es exactamente lo que quiero. Dado un número, cómo generar una paleta del número de colores. pero podemos hacerlo en R automáticamente?
ARN

Es asombroso. Sin embargo, hay mucha maquinaria detrás de ese sitio web. No creo que sea trivial volver a implementar. Sería bueno si i want huetuviera una API que permitiera que se consultara automáticamente (tal vez sí, no pasé mucho tiempo buscando)
Ben Bolker

8
@BenBolker - He hecho una idea esencial para una versión R de i want hue, aquí . La eficiencia podría mejorarse (por ejemplo, guardando muestras de color como objetos de datos), pero la idea general está ahí. (Cargar con devtools::source_gist('45b49da5e260a9fc1cd7'))
jbaums

36

También puedes probar el randomcoloRpaquete :

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

Puede ver que se elige un conjunto de colores muy distintos al visualizar en un gráfico circular (como lo sugieren otras respuestas aquí):

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

ingrese la descripción de la imagen aquí

Se muestra en un gráfico circular con 50 colores:

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

ingrese la descripción de la imagen aquí


3
Gracias. Tuve que usar unname(distinctColorPalette(n))para hacer que esto funcionara con ggplot. Supongo que ggplot necesita un vector sin nombre. col_vector <- unname(distinctColorPalette(n))y luego... + scale_color_manual(values=col_vector) ...
Gaurav

19

No es una respuesta a la pregunta de OP, pero vale la pena mencionar que existe el viridispaquete que tiene buenas paletas de colores para datos secuenciales. Son perceptualmente uniformes, daltónicos seguros y fáciles de imprimir.

Para obtener la paleta, simplemente instale el paquete y use la función viridis_pal(). Hay cuatro opciones "A", "B", "C" y "D" para elegir

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

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

También hay una excelente charla que explica la complejidad de los buenos mapas de colores en YouTube:

Un mejor mapa de colores predeterminado para Matplotlib | SciPy 2015 | Nathaniel Smith y Stéfan van der Walt


17
Esto no es tan adecuado para colores distintivos.
Christopher John

13

Puede usar colorRampPalettedesde la base o el RColorBrewerpaquete:

Con colorRampPalette, puede especificar colores de la siguiente manera:

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

También puede proporcionar códigos hexadecimales:

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

Con RColorBrewerusted podría usar colores de paletas preexistentes:

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

Mire el RColorBrewerpaquete para otras paletas disponibles. Espero que esto ayude.


1
Gracias. Me gusta la ultima opcion brewer.pal. pero está limitado hasta 9 colores. De hecho, tengo más de 9 categorías. Las primeras alternativas generan un degradado de colores, que no es tan distintivo como quiero.
ARN

2
no podrá elegir muchos colores "distintos". Puede obtener un máximo de 12, supongo. Debería consultar colorbrewer2.org y obtener los colores (hay una paleta de 12 colores si tengo razón).
Arun

Buscar más de 12 colores distintivos será difícil: creo que hay una discusión sobre eso en la página de
colorbrewer

eso está bien, siempre y cuando sean los "más" colores distintivos disponibles, incluso se volverán menos distintivos cuando el número aumente.
ARN

3
Si su problema son colores similares uno al lado del otro cuando se asignan a categorías adyacentes (como lo hará la paleta del arco iris), entonces simplemente podría aleatorizar la salida del arco iris con algo como: arco iris (n = 10) [muestra (10)]
David Roberts

11

Recomendaría utilizar una fuente externa para grandes paletas de colores.

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

tiene un servicio para componer cualquier tamaño de paleta de acuerdo con varios parámetros y

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

analiza el problema genérico desde la perspectiva de los diseñadores gráficos y ofrece muchos ejemplos de paletas utilizables.

Para comprender una paleta de valores RGB, solo tiene que copiar los valores en un vector como, por ejemplo:

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

Encontré un sitio web que ofrece una lista de 20 colores distintivos: 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')

¡Puedes intentarlo!


1
Esto realmente no responde a la pregunta, que se trata de generar n colores distintivos, no un conjunto de colores definidos. Intenta actualizar tu respuesta
Michal

1

Puede generar un conjunto de colores 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")

Estos colores son lo más distintos posible. Para esos colores similares, forman un gradiente para que pueda distinguir fácilmente las diferencias entre ellos.


0

Según tengo entendido, la búsqueda de colores distintivos está relacionada con la búsqueda eficiente desde un cubo unitario, donde 3 dimensiones del cubo son tres vectores a lo largo de los ejes rojo, verde y azul. Esto se puede simplificar para buscar en un cilindro (analogía HSV), donde se fija Saturación (S) y Valor (V) y se encuentran valores de Hue aleatorios. Funciona en muchos casos, y mira esto aquí:

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

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

Una forma alternativa es usar el paquete R "uniformemente" https://cran.r-project.org/web/packages/uniformly/index.html

y esta función simple puede generar colores distintivos:

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

Se puede pensar en una función un poco más complicada mediante la búsqueda de cuadrícula:

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 funciones por:

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

Sin embargo, tenga en cuenta que definir una paleta distinta con colores perceptibles humanos no es simple. ¿Cuál de los enfoques anteriores genera un conjunto diverso de colores aún no se ha probado?


0

Puede usar el paquete Polychrome para este propósito. Solo requiere la cantidad de colores y unos pocos seedcolors. Por ejemplo:

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

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

Puede obtener más información sobre este paquete en https://www.jstatsoft.org/article/view/v090c01 .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.