Come assegnare i colors alle variabili categoriali in ggplot2 che hanno una mapping stabile?

Mi sono alzato alla velocità con R nell’ultimo mese.

Ecco la mia domanda:

Qual è un buon modo per assegnare i colors alle variabili categoriali in ggplot2 che hanno una mapping stabile? Ho bisogno di colors coerenti attraverso una serie di grafici che hanno sottoinsiemi diversi e un numero diverso di variabili categoriali.

Per esempio,

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line() 

dove categoricalData ha 5 livelli.

E poi

 plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset, color=categoricaldData.subset)) + geom_line() 

dove categoricalData.subset ha 3 livelli.

Tuttavia, un livello particolare che si trova in entrambi i set avrà un colore diverso, il che rende più difficile leggere i grafici insieme.

Devo creare un vettore di colors nel frame dati? O c’è un altro modo per assegnare colors specifici alle categorie?

Per situazioni semplici come l’esatto esempio nel PO, sono d’accordo sul fatto che la risposta di Thierry sia la migliore. Tuttavia, ritengo sia utile indicare un altro approccio che diventa più semplice quando si tenta di mantenere schemi di colors coerenti su più frame di dati che non sono tutti ottenuti sottoponendo a sottomissione un singolo frame di dati di grandi dimensioni. Gestire i livelli dei fattori in più frame di dati può diventare noioso se vengono estratti da file separati e non tutti i livelli di fattore appaiono in ogni file.

Un modo per risolvere questo problema è creare una scala colore manuale personalizzata come segue:

 #Some test data dat <- data.frame(x=runif(10),y=runif(10), grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE) #Create a custom color scale library(RColorBrewer) myColors <- brewer.pal(5,"Set1") names(myColors) <- levels(dat$grp) colScale <- scale_colour_manual(name = "grp",values = myColors) 

e quindi aggiungere la scala di colors sulla trama secondo necessità:

 #One plot with all the data p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point() p1 <- p + colScale #A second plot with only four of the levels p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale 

La prima trama appare così:

inserisci la descrizione dell'immagine qui

e la seconda trama appare così:

inserisci la descrizione dell'immagine qui

In questo modo non è necessario ricordare o controllare ogni frame di dati per vedere che hanno i livelli appropriati.

Sono nella stessa situazione indicata da malcook nel suo commento : sfortunatamente la risposta di Thierry non funziona con ggplot2 versione 0.9.3.1.

 png("figure_%d.png") set.seed(2014) library(ggplot2) dataset <- data.frame(category = rep(LETTERS[1:5], 100), x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100))) dataset$fCategory <- factor(dataset$category) subdata <- subset(dataset, category %in% c("A", "D", "E")) ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point() ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point() 

Ecco la prima cifra:

ggplot A-E, colori misti

e la seconda cifra:

ggplot ADE, colori misti

Come possiamo vedere i colors non rimangono fissi, per esempio E passa da magenta a blu.

Come suggerito da malcook nel suo commento e da hadley nel suo commento, il codice che utilizza i limits funziona correttamente:

 ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point() + scale_colour_discrete(drop=TRUE, limits = levels(dataset$fCategory)) 

dà la seguente figura, che è corretta:

ggplot corretto

Questo è l'output di sessionInfo() :

 R version 3.0.2 (2013-09-25) Platform: x86_64-pc-linux-gnu (64-bit) locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] methods stats graphics grDevices utils datasets base other attached packages: [1] ggplot2_0.9.3.1 loaded via a namespace (and not attached): [1] colorspace_1.2-4 dichromat_2.0-0 digest_0.6.4 grid_3.0.2 [5] gtable_0.1.2 labeling_0.2 MASS_7.3-29 munsell_0.4.2 [9] plyr_1.8 proto_0.3-10 RColorBrewer_1.0-5 reshape2_1.2.2 [13] scales_0.2.3 stringr_0.6.2 

La soluzione più semplice è convertire la variabile categoriale in un fattore prima del subset. La linea di fondo è che hai bisogno di una variabile fattore con esattamente gli stessi livelli in tutti i tuoi sottogruppi.

 library(ggplot2) dataset <- data.frame(category = rep(LETTERS[1:5], 100), x = rnorm(500, mean = rep(1:5, 100)), y = rnorm(500, mean = rep(1:5, 100))) dataset$fCategory <- factor(dataset$category) subdata <- subset(dataset, category %in% c("A", "D", "E")) 

Con una variabile di carattere

 ggplot(dataset, aes(x = x, y = y, colour = category)) + geom_point() ggplot(subdata, aes(x = x, y = y, colour = category)) + geom_point() 

Con una variabile fattore

 ggplot(dataset, aes(x = x, y = y, colour = fCategory)) + geom_point() ggplot(subdata, aes(x = x, y = y, colour = fCategory)) + geom_point() 

Sulla base della risposta molto utile di joran, sono riuscito a trovare questa soluzione per una scala di colors stabile per un fattore booleano ( TRUE , FALSE ).

 boolColors <- as.character(c("TRUE"="#5aae61", "FALSE"="#7b3294")) boolScale <- scale_colour_manual(name="myboolean", values=boolColors) ggplot(myDataFrame, aes(date, duration)) + geom_point(aes(colour = myboolean)) + boolScale 

Poiché ColorBrewer non è molto utile con le scale di colors binari, i due colors necessari sono definiti manualmente.

Qui myboolean è il nome della colonna in myDataFrame che myDataFrame il fattore TRUE / FALSE. date e duration sono i nomi delle colonne da associare all'asse xey del grafico in questo esempio.

Questo è un vecchio post, ma stavo cercando una risposta a questa stessa domanda,

Perché non provare qualcosa come:

 scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00")) 

Se hai valori categoriali, non vedo una ragione per cui questo non dovrebbe funzionare.