Fügen Sie dem Liniendiagramm ggplot2 eine Legende hinzu

143

Ich habe eine Frage zu Legenden in ggplot2. Ich habe es geschafft, drei Linien im selben Diagramm zu zeichnen und möchte eine Legende mit den drei verwendeten Farben hinzufügen. Dies ist der verwendete Code

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

und die Ausgabe

ggplot drei Zeilen

Ich möchte eine Legende mit den drei verwendeten Farben und dem Namen der Variablen (TempMax, TempMedia und TempMin) hinzufügen. Ich habe versucht

scale_colour_manual

kann aber den genauen Weg nicht finden.

Leider wurden die Originaldaten von der verlinkten Seite gelöscht und konnten nicht wiederhergestellt werden. Sie stammten jedoch aus Meteodatendateien mit diesem 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
quelle
Ich bin immer noch neugierig, ob Legenden an einzelne Elemente der Handlung gebunden werden können (z. B. verschiedene geom_line).
Etienne Low-Décarie
Wenn Sie nur 3 Zeilen haben, würde ich vorschlagen, das dirrectlabels-Paket zu betrachten. (LINK)
Tyler Rinker
@ TylerRinker Ich hatte es vorher für andere Zwecke verwendet, aber jetzt funktioniert die Antwort von csgillespie besser für mich
Pacomet
@ EtienneLow-Décarie Sie können, aber im Allgemeinen nur, wenn sie unterschiedliche Ästhetik verwenden. zB Zuordnung eines Satzes von Linien zur Farbe und eines anderen zum Linientyp. In der Regel geben Sie in diesem Fall auch separate Daten an jedes Geom weiter.
Joran

Antworten:

82

Ich neige dazu festzustellen, dass ich es falsch mache, wenn ich einzelne Farben in mehreren Geoms spezifiziere. So würde ich Ihre Daten zeichnen:

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

Alles was übrig bleibt ist ein einfacher ggplot Befehl:

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

Beispielplot

Geben Sie hier die Bildbeschreibung ein

csgillespie
quelle
87
Ich bin immer noch neugierig, wie man Legenden hinzufügt, die mit dem separaten Hinzufügen von Elementen wie geom_line verbunden sind, was meiner Meinung nach der ursprüngliche Zweck der Frage war.
Etienne Low-Décarie
201

Da @Etienne gefragt hat, wie dies zu tun ist, ohne die Daten zu schmelzen (was im Allgemeinen die bevorzugte Methode ist, aber ich erkenne, dass es einige Fälle gibt, in denen dies nicht möglich ist), präsentiere ich die folgende Alternative.

Beginnen Sie mit einer Teilmenge der Originaldaten:

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

Sie können den gewünschten Effekt erzielen, indem Sie (und dies bereinigt auch den ursprünglichen Plotcode):

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

Die Idee ist, dass jede Linie eine Farbe erhält, indem die colourÄsthetik einer konstanten Zeichenfolge zugeordnet wird. Am einfachsten ist es, die Zeichenfolge auszuwählen, die in der Legende angezeigt werden soll. Die Tatsache, dass es in diesem Fall mit dem Namen der dargestellten yVariablen identisch ist, ist nicht signifikant. Es kann sich um einen beliebigen Satz von Zeichenfolgen handeln. Es ist sehr wichtig, dass dies im aesAnruf enthalten ist. Sie erstellen eine Zuordnung zu dieser "Variablen".

scale_colour_manualkann diese Zeichenfolgen nun den entsprechenden Farben zuordnen. Das Ergebnis ist Geben Sie hier die Bildbeschreibung ein

In einigen Fällen muss die Zuordnung zwischen den Ebenen und Farben explizit gemacht werden, indem die Werte in der manuellen Skala benannt werden (danke an @DaveRGP für den Hinweis):

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

(mit der gleichen Zahl wie zuvor). Bei benannten Werten können die Unterbrechungen verwendet werden, um die Reihenfolge in der Legende festzulegen, und jede Reihenfolge kann in den Werten verwendet werden.

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
quelle
2
Ich liebe diese Lösung, aber ich denke, es kann eine Einschränkung geben. Gibt es ein alphabetisches Sortierproblem zwischen der Zuordnung der Variablen "Unterbrechungen" und "Werte"? TempM {a] x, TempM {e} dia und TempM {i} n sind ordentlich sortiert. Wenn ich dies jedoch an meine Variablennamen anpasse, scheinen die Farben in alphabetischer Reihenfolge mit den 'Unterbrechungen' übereinzustimmen, nicht in der Reihenfolge . Kann das Obige geklärt / verfeinert werden, um dies zu reflektieren / zu beheben?
DaveRGP
3
Ich habe es geschafft, eine Lösung für das Problem zu finden, das ich zuvor bei der Farbbestellung gekauft habe. Verwenden Sie das Formular, scale_colour_manual("", values = c("TempMax" = "red", "TempMedia" = "green", "TempMin" = "blue"))in dem TempMax, TempMedia und TempMin als Farbargument angegeben sind, wie in der obigen Antwort.
DaveRGP
@ DaveRGP Könnte es als ein Fehler von ggplot angesehen werden?
Alessandro Jacopson
1
@StellaBiderman Danke. Es ist schön zu wissen, dass diese Antwort (fast) 5 Jahre (!) Später noch nützlich ist.
Brian Diggs
1
@BrianDiggs Du würdest nicht zufällig wissen, wie man diese Anzeige zu einem Punkt in der Skala macht, im Gegensatz zu einer Linie, oder?
Stella Biderman
2

Die von @Brian Diggs vorgeschlagene Lösung gefällt mir sehr gut. In meinem Fall erstelle ich die Liniendiagramme jedoch in einer Schleife, anstatt sie explizit anzugeben, da ich apriori nicht weiß, wie viele Diagramme ich haben werde. Als ich versuchte, den Code von @ Brian anzupassen, hatte ich einige Probleme mit dem richtigen Umgang mit den Farben. Es stellte sich heraus, dass ich die ästhetischen Funktionen modifizieren musste. Falls jemand das gleiche Problem hat, ist hier der Code, der für mich funktioniert hat.

Ich habe den gleichen Datenrahmen wie @Brian verwendet:

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

In meinem Fall generiere ich my.colsund my.namesdynamisch, aber ich möchte die Dinge nicht unnötig kompliziert machen, deshalb gebe ich sie hier explizit an. Diese drei Zeilen erleichtern die Reihenfolge der Legende und die Zuweisung von Farben.

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

Und hier ist die Handlung:

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

Geben Sie hier die Bildbeschreibung ein

Justyna
quelle
2
Bei dieser Komplexität wird es wirklich viel einfacher, Ihre Daten einfach in die ggploterwartete lange Form umzuformen.
Axeman
1
Ich denke nicht, dass es die Komplexität im Vergleich zu der ursprünglichen Antwort von @Brian wirklich erhöht. Außerdem möchten einige Leute dies möglicherweise tun, ohne die Daten neu zu formen.
Justyna
... und dieser Ansatz erlaubt verschiedene Geoms (Handlungstypen) nach Variablen
Mac