2011-05-20 13 views
19

Tengo un dataframe R (df) que estoy trazando como un gráfico de barras en ggplot2 y coloreado en base a una columna en el dataframe (df$type). En este momento, estoy usando el patrón de coloreado predeterminado (scale_fill_brewer) para asignar colores.En R, ¿cómo cambio el valor del color de solo un valor en scale_fill_brewer de ggplot2?

¿Cómo puedo asignar el color negro a un valor, (df$type == -1) y usar scale_fill_brewer para asignar el resto de los colores? (todos los demás tipos de df $ están dentro de un conjunto de enteros de 1 a X, donde X es el número de valores únicos)

Hasta ahora, he podido hacer esto manualmente calculando el conjunto de colores scale_fill_brewer utiliza para N elementos diferentes que luego dejan el color negro y lo pasan al scale_fill_manual.

rhg_cols1<- c("#000000","#F8766D","#7CAE00","#00BFC4","#C77CFF") 
ggplot(y=values,data=df, aes(x=name, fill=factor(type))) + 
    geom_bar()+ scale_fill_manual(values = rhg_cols1) 

El problema es que necesito una solución que funciona sin asignar manualmente los colores mediante el uso de una calculadora de color hexadecimal para averiguar los valores hexadecimales de scale_fill_brewer.

algo como:

ggplot(y=values,data=df, aes(x=name, fill=factor(type))) + 
    geom_bar()+ scale_fill_brewer(value(-1, "black") 

Gracias!

EDIT: La solución debe trabajar durante más de 30 colores y el trabajo para "Set2" de ColorBrewer

+1

Me preguntaba acerca de la misma. Sería genial si 'scale_fill_manual()' y otros aceptaran un vector incompleto de especificaciones, p. 'scale_fill_manual (values ​​= c ('- 1' = 'black'))' y comprende que los otros colores se deben seleccionar automáticamente como de costumbre. –

Respuesta

31

El paquete contiene RColorBrewer las paletas y se puede utilizar la función de brewer.pal para devolver una paleta de colores de su elección.

Por ejemplo, una paleta de color azul secuencial de 5 colores:

library(RColorBrewer) 
my.cols <- brewer.pal(5, "Blues") 
my.cols 

[1] "#EFF3FF" "#BDD7E7" "#6BAED6" "#3182BD" "#08519C" 

, usted puede obtener una lista de nombres de la paleta válidos en los archivos de ayuda ?brewer.pal. Estos nombres se corresponden con los nombres en el sitio web ColorBrewer.

Ahora puede utilizar o modificar los resultados y transmitirlos a ggplot utilizando el scale_manual_fill como usted sugiere:

my.cols[1] <- "#000000" 

library(ggplot2) 
df <- data.frame(x=1:5, type=1:5) 
ggplot(df, aes(x=x, fill=factor(type))) + 
    geom_bar(binwidth=1)+ 
    scale_fill_manual(values = my.cols) 

enter image description here

+0

+1 para detalles ... –

+0

Gracias por su respuesta muy detallada. Desafortunadamente Set2 solo devuelve 8 colores, y en algunas situaciones tengo más que eso. – wespiserA

+0

Sí, hasta donde sé, casi todas las paletas ColorBrewer tienen un límite superior de 8 colores. También puedes probar 'scale_fill_hue'. – Andrie

20

Si es necesario distinguir entre esta cantidad (más de 30) diferentes categorías Probablemente necesites hacer una copia de seguridad y dedicar más tiempo a pensar estratégicamente en el proyecto: será casi imposible crear un conjunto de 30 colores que sean realmente distinguibles (especialmente de forma independiente de la plataforma/canal de representación).

Básicamente, no hay ninguna solución que funcione con Set2 y más de 30 colores. Algunas de las paletas CB (Set3 y Paired; library(RColorBrewer); display.brewer.all(n=12)) permiten hasta 12 colores.

edit: el OP desea realizar análisis de datos exploratorios con colores buenos y distinguibles que no se rompen si hay muchas categorías. Yo sugeriría algo en este sentido:

library(RColorBrewer) 
my.cols <- function(n) { 
    black <- "#000000" 
    if (n <= 9) { 
    c(black,brewer.pal(n-1, "Set2")) 
    } else { 
    c(black,hcl(h=seq(0,(n-2)/(n-1), 
        length=n-1)*360,c=100,l=65,fixup=TRUE)) 
    } 
} 

library(ggplot2) 
d <- data.frame(z=1:10) 
g1 <- qplot(z,z,data=d,colour=factor(z))+opts(legend.position="none") 
g1 + scale_colour_manual(values=my.cols(9)) 
g1 + scale_colour_manual(values=my.cols(10)) 
## check that we successfully recreated ggplot2 internals 
## g1+scale_colour_discrete() 

Creo que esto funciona razonablemente bien (se puede sustituir Set3 y un punto de corte de 13 colores si usted prefiere).El único inconveniente (que se me ocurre) es la discontinuidad entre las tramas con 9 y 10 colores.

El subir con una solución mejor para recoger conjuntos de N colores distinguibles de una manera programática va a ser muy difícil ...

+0

de todos modos, gracias por tu tiempo. – wespiserA

+2

Una solución más interesante/desafiante sería encontrar un conjunto de puntos que caigan dentro de la cuña HCL en luminancia = 65 y que estén lo más espaciados/separados posible. No es trivial ... –

+1

Siguiendo el comentario anterior de @ Ben, 'rainbow_hcl' en el paquete ** colorspace ** facilita la construcción de paletas de colores HCL espaciados uniformemente. Por ejemplo: 'biblioteca (espacio de color); plot (1:10, col = rainbow_hcl (n = 10, c = 100, l = 65), pch = 16, cex = 6) '. –

Cuestiones relacionadas