manually guides ggplot custom color change r ggplot2 legend r-faq

r - custom - guides ggplot2 legend



Agregar leyenda al diagrama de lĂ­neas ggplot2 (3)

Tengo una pregunta sobre leyendas en ggplot2. Logré trazar tres líneas en el mismo gráfico y quiero agregar una leyenda con los tres colores utilizados. Este es el código usado

library(ggplot2) require(RCurl) link<-getURL("https://dl.dropbox.com/s/ds5zp9jonznpuwb/dat.txt") datos<- read.csv(textConnection(link),header=TRUE,sep=";") datos$fecha <- as.POSIXct(datos[,1], format="%d/%m/%Y") temp = ggplot(data=datos,aes(x=fecha, y=TempMax,colour="1")) + geom_line(colour="red") + opts(title="TITULO") + ylab("Temperatura (C)") + xlab(" ") + scale_y_continuous(limits = c(-10,40)) + geom_line(aes(x=fecha, y=TempMedia,colour="2"),colour="green") + geom_line(aes(x=fecha, y=TempMin,colour="2"),colour="blue") + scale_colour_manual(values=c("red","green","blue")) temp

y la salida

Me gustaría agregar una leyenda con los tres colores utilizados y el nombre de la variable (TempMax, TempMedia y TempMin). Yo he tratado

scale_colour_manual

pero no puede encontrar la forma exacta.

Lamentablemente, los datos originales se eliminaron del sitio vinculado y no se pudieron recuperar. Pero vinieron de archivos de datos meteo con este formato

"date","Tmax","Tmin","Tmed","Precip.diaria","Wmax","Wmed" 2000-07-31 00:00:00,-1.7,-1.7,-1.7,-99.9,20.4,20.4 2000-08-01 00:00:00,22.9,19,21.11,-99.9,6.3,2.83 2000-08-03 00:00:00,24.8,12.3,19.23,-99.9,6.8,3.87 2000-08-04 00:00:00,20.3,9.4,14.4,-99.9,8.3,5.29 2000-08-08 00:00:00,25.7,14.4,19.5,-99.9,7.9,3.22 2000-08-09 00:00:00,29.8,16.2,22.14,-99.9,8.5,3.27 2000-08-10 00:00:00,30,17.8,23.5,-99.9,7.7,3.61 2000-08-11 00:00:00,27.5,17,22.68,-99.9,8.8,3.85 2000-08-12 00:00:00,24,13.3,17.32,-99.9,8.4,3.49


Dado que @Etienne preguntó cómo hacer esto sin fundir los datos (que en general es el método preferido, pero reconozco que puede haber algunos casos donde eso no es posible), presento la siguiente alternativa.

Comience con un subconjunto de los datos originales:

datos <- structure(list(fecha = structure(c(1317452400, 1317538800, 1317625200, 1317711600, 1317798000, 1317884400, 1317970800, 1318057200, 1318143600, 1318230000, 1318316400, 1318402800, 1318489200, 1318575600, 1318662000, 1318748400, 1318834800, 1318921200, 1319007600, 1319094000), class = c("POSIXct", "POSIXt"), tzone = ""), TempMax = c(26.58, 27.78, 27.9, 27.44, 30.9, 30.44, 27.57, 25.71, 25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 26.58, 26.18, 25.19, 24.19, 27.65, 23.92), TempMedia = c(22.88, 22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52, 19.71, 20.73, 23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 20.45, 19.42, 19.97, 19.61), TempMin = c(19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 16.88, 16.82, 14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01, 16.95, 17.55, 15.21, 14.22, 16.42)), .Names = c("fecha", "TempMax", "TempMedia", "TempMin"), row.names = c(NA, 20L), class = "data.frame")

Puede obtener el efecto deseado por (y esto también limpia el código de trazado original):

ggplot(data = datos, aes(x = fecha)) + geom_line(aes(y = TempMax, colour = "TempMax")) + geom_line(aes(y = TempMedia, colour = "TempMedia")) + geom_line(aes(y = TempMin, colour = "TempMin")) + scale_colour_manual("", breaks = c("TempMax", "TempMedia", "TempMin"), values = c("red", "green", "blue")) + xlab(" ") + scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + labs(title="TITULO")

La idea es que a cada línea se le dé un color mapeando la estética del colour a una cadena constante. Elegir la cadena que es lo que desea que aparezca en la leyenda es la más fácil. El hecho de que en este caso sea el mismo que el nombre de la variable y que se traza no es significativo; podría ser cualquier conjunto de cadenas. Es muy importante que esto esté dentro de la llamada de aes ; está creando un mapeo a esta "variable".

scale_colour_manual ahora puede asignar estas cadenas a los colores apropiados. El resultado es

En algunos casos, la asignación entre los niveles y los colores debe hacerse explícita nombrando los valores en la escala manual (gracias a @DaveRGP para señalar esto):

ggplot(data = datos, aes(x = fecha)) + geom_line(aes(y = TempMax, colour = "TempMax")) + geom_line(aes(y = TempMedia, colour = "TempMedia")) + geom_line(aes(y = TempMin, colour = "TempMin")) + scale_colour_manual("", values = c("TempMedia"="green", "TempMax"="red", "TempMin"="blue")) + xlab(" ") + scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + labs(title="TITULO")

(dando la misma figura que antes). Con valores con nombre, los descansos se pueden usar para establecer el orden en la leyenda y cualquier orden se puede usar en los valores.

ggplot(data = datos, aes(x = fecha)) + geom_line(aes(y = TempMax, colour = "TempMax")) + geom_line(aes(y = TempMedia, colour = "TempMedia")) + geom_line(aes(y = TempMin, colour = "TempMin")) + scale_colour_manual("", breaks = c("TempMedia", "TempMax", "TempMin"), values = c("TempMedia"="green", "TempMax"="red", "TempMin"="blue")) + xlab(" ") + scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + labs(title="TITULO")


Me gusta mucho la solución propuesta por @Brian Diggs. Sin embargo, en mi caso, creo los gráficos de líneas en un bucle en lugar de darlos explícitamente porque no sé a priori cuántas parcelas tendré. Cuando traté de adaptar el código de @ Brian, tuve algunos problemas para manejar los colores correctamente. Resultó que necesitaba modificar las funciones estéticas. En caso de que alguien tenga el mismo problema, aquí está el código que funcionó para mí.

Usé el mismo marco de datos que @Brian:

data <- structure(list(month = structure(c(1317452400, 1317538800, 1317625200, 1317711600, 1317798000, 1317884400, 1317970800, 1318057200, 1318143600, 1318230000, 1318316400, 1318402800, 1318489200, 1318575600, 1318662000, 1318748400, 1318834800, 1318921200, 1319007600, 1319094000), class = c("POSIXct", "POSIXt"), tzone = ""), TempMax = c(26.58, 27.78, 27.9, 27.44, 30.9, 30.44, 27.57, 25.71, 25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 26.58, 26.18, 25.19, 24.19, 27.65, 23.92), TempMed = c(22.88, 22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52, 19.71, 20.73, 23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 20.45, 19.42, 19.97, 19.61), TempMin = c(19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 16.88, 16.82, 14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01, 16.95, 17.55, 15.21, 14.22, 16.42)), .Names = c("month", "TempMax", "TempMed", "TempMin"), row.names = c(NA, 20L), class = "data.frame")

En mi caso, genero my.cols y my.names dinámicamente, pero no quiero complicar innecesariamente las cosas, así que las doy explícitamente aquí. Estas tres líneas facilitan el orden de la leyenda y la asignación de colores.

my.cols <- heat.colors(3, alpha=1) my.names <- c("TempMin", "TempMed", "TempMax") names(my.cols) <- my.names

Y aquí está la trama:

p <- ggplot(data, aes(x = month)) for (i in 1:3){ p <- p + geom_line(aes_(y = as.name(names(data[i+1])), colour = colnames(data[i+1])))#as.character(my.names[i]))) } p + scale_colour_manual("", breaks = as.character(my.names), values = my.cols) p


Tiendo a encontrar que si estoy especificando colores individuales en múltiples geom, lo estoy haciendo mal. Así es como trazaría sus datos:

##Subset the necessary columns dd_sub = datos[,c(20, 2,3,5)] ##Then rearrange your data frame library(reshape2) dd = melt(dd_sub, id=c("fecha"))

Todo lo que queda es un simple comando ggplot:

ggplot(dd) + geom_line(aes(x=fecha, y=value, colour=variable)) + scale_colour_manual(values=c("red","green","blue"))

Ejemplo de diagrama