Dodaj legendę do wykresu linii ggplot2
Mam pytanie odnośnie legend w ggplot2. Udało mi się narysować trzy linie na tym samym wykresie i chcę dodać legendę z trzema używanymi kolorami. Jest to użyty kod
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
I wyjście
Chciałbym dodać legendę z trzema używanymi kolorami i nazwą zmiennej (TempMax, TempMedia i TempMin). Próbowałem
scale_colour_manual
Ale nie mogę znaleźć dokładnej drogi.
Niestety oryginalne dane zostały usunięte z linked site i nie można być odzyskane. Ale pochodzą one z plików danych meteo o tym formacie
"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
3 answers
Zazwyczaj stwierdzam, że jeśli określam poszczególne kolory w wielu geom-ach, robię to źle. Oto jak wykreśliłbym Twoje dane:
##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"))
Pozostało tylko proste polecenie ggplot:
ggplot(dd) + geom_line(aes(x=fecha, y=value, colour=variable)) +
scale_colour_manual(values=c("red","green","blue"))
Przykładowy wykres
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 21:06:21
Ponieważ @ Etienne zapytał, Jak to zrobić bez topienia danych (co ogólnie jest preferowaną metodą, ale zdaję sobie sprawę, że mogą być przypadki, w których nie jest to możliwe), przedstawiam następującą alternatywę.
Zacznij od podzbioru oryginalnych danych:
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")
Można uzyskać pożądany efekt poprzez (i to również oczyszcza oryginalny kod kreślenia):
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")
Chodzi o to, że każda linia otrzymuje kolor poprzez odwzorowanie colour
estetyki na stałą sznurek. Wybór ciągu, który jest tym, co chcesz wyświetlić w legendzie, jest najłatwiejszy. Fakt, że w tym przypadku jest to to samo, co nazwa wykreślanej zmiennej y
, nie jest istotny; może to być dowolny zbiór łańcuchów. Bardzo ważne jest, aby to było wewnątrz wywołania aes
; tworzysz mapowanie do tej "zmiennej".
scale_colour_manual
można teraz mapować te ciągi do odpowiednich kolorów. Rezultatem jest
W niektórych przypadkach mapowanie między poziomami i kolorami należy wyraźnie określić, nazywając wartości w skali ręcznej (dzięki @ DaveRGP za wskazanie tego):
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")
(podając tę samą liczbę co poprzednio). W przypadku nazwanych wartości, podziały mogą być używane do ustawiania kolejności w legendzie i dowolnej kolejności w wartościach.
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")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:01
Bardzo podoba mi się rozwiązanie zaproponowane przez @Brian Diggs. Jednak w moim przypadku tworzę działki linii w pętli, a nie dając im wyraźnie, ponieważ Nie wiem apriori, ile działek będę miał. Kiedy próbowałem dostosować kod @ Brian, napotkałem pewne problemy z prawidłową obsługą kolorów. Okazało się, że musiałem zmodyfikować funkcje estetyczne. W przypadku, gdy ktoś ma ten sam problem, Oto kod, który działał dla mnie.
Użyłem tej samej ramki danych, co @ 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")
W moim przypadku generuję my.cols
i my.names
dynamicznie, ale nie chcę niepotrzebnie komplikować rzeczy, więc podaję je wyraźnie tutaj. Te trzy linie ułatwiają porządkowanie legendy i przypisywanie kolorów.
my.cols <- heat.colors(3, alpha=1)
my.names <- c("TempMin", "TempMed", "TempMax")
names(my.cols) <- my.names
A oto fabuła:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-02 17:35:25