web-dev-qa-db-fra.com

Ajouter une légende au tracé de la ligne ggplot2

J'ai une question sur les légendes de ggplot2. J'ai réussi à tracer trois lignes dans le même graphique et je voulais ajouter une légende avec les trois couleurs utilisées. C'est le code utilisé

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

et la sortie

ggplot three lines

J'aimerais ajouter une légende avec les trois couleurs utilisées et le nom de la variable (TempMax, TempMedia et TempMin). j'ai essayé

scale_colour_manual

mais ne trouve pas le chemin exact.

Malheureusement, les données d'origine ont été supprimées du site lié et n'ont pas pu être récupérées. Mais ils venaient de fichiers de données météo avec ce format

"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
131
pacomet

J'ai tendance à penser que si je spécifie des couleurs individuelles dans plusieurs géom, je le fais mal. Voici comment je voudrais tracer vos données:

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

Tout ce qui reste est une simple commande de ggplot:

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

Exemple de tracé

enter image description here

76
csgillespie

Puisque @ Etienne a demandé comment faire cela sans faire fondre les données (ce qui est généralement la méthode préférée, mais je reconnais qu'il peut arriver que cela ne soit pas possible), je présente l'alternative suivante.

Commencez avec un sous-ensemble des données d'origine:

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

Vous pouvez obtenir l’effet souhaité par (et cela nettoie également le code de tracé initial):

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

L'idée est de donner une couleur à chaque ligne en mappant l'esthétique colour sur une chaîne constante. Le choix de la chaîne que vous souhaitez voir apparaître dans la légende est le plus simple. Le fait qu'il s'agisse dans ce cas du même nom que le nom de la variable y en cours de tracé n'est pas significatif; il pourrait s'agir de n'importe quel jeu de chaînes. Il est très important que cela se trouve dans l'appel aes; vous créez un mappage à cette "variable".

scale_colour_manual peut maintenant mapper ces chaînes aux couleurs appropriées. Le résultat est enter image description here

Dans certains cas, la correspondance entre les niveaux et les couleurs doit être explicite en nommant les valeurs dans l'échelle manuelle (grâce à @ DaveRGP pour l'avoir signalé):

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

(donnant le même chiffre qu'avant). Avec les valeurs nommées, les sauts peuvent être utilisés pour définir l'ordre dans la légende et n'importe quel ordre peut être utilisé dans les valeurs.

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

177
Brian Diggs

J'aime beaucoup la solution proposée par @Brian Diggs. Cependant, dans mon cas, je crée les tracés linéaires dans une boucle plutôt que de les donner explicitement, car je ne sais pas a priori combien de tracés je vais avoir. Lorsque j'ai essayé d'adapter le code @ Brian, j'ai rencontré quelques problèmes pour gérer correctement les couleurs. Il s'est avéré que je devais modifier les fonctions esthétiques. Au cas où quelqu'un aurait le même problème, voici le code qui a fonctionné pour moi.

J'ai utilisé le même cadre de données 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")  

Dans mon cas, je génère my.cols et my.names de manière dynamique, mais je ne veux pas compliquer inutilement les choses, je les donne donc explicitement ici. Ces trois lignes facilitent le classement de la légende et l'attribution des couleurs.

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

Et voici l'intrigue:

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

enter image description here

3
Justyna