Ajouter une légende au tracé linéaire ggplot2

143

J'ai une question sur les légendes dans ggplot2. J'ai réussi à tracer trois lignes dans le même graphique et je souhaite 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 trois lignes

Je voudrais 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 peut pas trouver 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 provenaient 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
Pacomet
la source
Je suis toujours curieux de savoir si les légendes peuvent être liées à des éléments séparés de l'intrigue (tels que différents geom_line).
Etienne Low-Décarie
Si vous n'avez que 3 lignes, je vous suggère de regarder le package dirrectlabels. (LIEN)
Tyler Rinker
@TylerRinker Je l'avais déjà utilisé à d'autres fins, mais maintenant la réponse de csgillespie fonctionne mieux pour moi
pacomet
@ EtienneLow-Décarie Vous pouvez, mais en général seulement s'ils utilisent une esthétique différente. par exemple, mapper un ensemble de lignes à la couleur et un autre au type de ligne. En règle générale, vous transmettriez également des données distinctes à chaque geom dans ce cas.
joran

Réponses:

82

J'ai tendance à trouver que si je spécifie des couleurs individuelles dans plusieurs geom, je le fais mal. Voici comment je tracerais 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"))

Il ne reste qu'une simple commande ggplot:

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

Exemple de tracé

entrez la description de l'image ici

csgillespie
la source
87
Je suis toujours curieux de savoir comment ajouter des légendes associées à l'ajout séparé d'éléments tels que geom_line, ce qui, selon moi, était le but initial de la question.
Etienne Low-Décarie
202

Puisque @Etienne a demandé comment faire cela sans fondre les données (ce qui est en général la méthode préférée, mais je reconnais qu'il peut y avoir des cas où cela n'est pas possible), je présente l'alternative suivante.

Commencez par 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é en (et cela nettoie également le code de traçage d'origine):

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 que chaque ligne reçoit une couleur en mappant l' colouresthétique à 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 que dans ce cas il soit identique au nom de la yvariable tracée n'est pas significatif; il peut s'agir de n'importe quel ensemble de chaînes. Il est très important que ce soit à l'intérieur de l' aesappel; vous créez un mappage vers cette "variable".

scale_colour_manualpeut maintenant mapper ces chaînes aux couleurs appropriées. Le résultat est entrez la description de l'image ici

Dans certains cas, le mappage entre les niveaux et les couleurs doit être rendu explicite en nommant les valeurs dans l'échelle manuelle (merci à @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 que précédemment). Avec des 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")

Brian Diggs
la source
2
J'adore cette solution, mais je pense qu'il peut y avoir une limitation. Y a-t-il un problème de tri alphabétique entre le mappage des variables «breaks» et «values»? TempM {a] x, TempM {e} dia et TempM {i} n trient parfaitement, bien que lorsque j'adapte cela à mes noms de variables, les couleurs semblent correspondre dans l'ordre alphabétique aux 'breaks', pas dans l'ordre d'entrée . Ce qui précède peut-il être clarifié / affiné pour refléter / corriger cela?
DaveRGP
3
J'ai réussi à trouver une solution au problème que j'ai acheté plus tôt concernant la commande des couleurs. utilisez le formulaire scale_colour_manual("", values = c("TempMax" = "red", "TempMedia" = "green", "TempMin" = "blue"))où TempMax, TempMedia et TempMin sont spécifiés comme argument de couleur comme dans la réponse ci-dessus.
DaveRGP
@DaveRGP Pourrait-il être considéré comme un bogue de ggplot?
Alessandro Jacopson
1
@StellaBiderman Merci. Il est bon de savoir que cette réponse est toujours utile (presque) 5 ans (!) Plus tard.
Brian Diggs
1
@BrianDiggs Vous ne sauriez pas comment faire de ce spectacle un point dans l'échelle par opposition à une ligne?
Stella Biderman
2

J'aime beaucoup la solution proposée par @Brian Diggs. Cependant, dans mon cas, je crée les graphiques linéaires en boucle plutôt que de les donner explicitement car je ne sais pas a priori combien de parcelles je vais avoir. Lorsque j'ai essayé d'adapter le code de @ Brian, j'ai rencontré des problèmes pour gérer correctement les couleurs. Il s'est avéré que j'avais besoin de 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.colset my.namesdynamiquement, mais je ne veux pas compliquer inutilement les choses donc je les donne 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

entrez la description de l'image ici

Justyna
la source
2
À cette complexité, il devient vraiment beaucoup plus facile de simplement remodeler vos données dans la forme longue ggplotattendue.
Axeman
1
Je ne pense pas que cela ajoute vraiment de la complexité par rapport à la réponse originale publiée par @Brian. En outre, certaines personnes peuvent vouloir le faire sans remodeler les données.
Justyna
... et cette approche permet différents geoms (types de parcelles) par variable
mac