Thêm huyền thoại vào cốt truyện dòng ggplot2


143

Tôi có một câu hỏi về truyền thuyết trong ggplot2. Tôi đã quản lý để vẽ ba dòng trong cùng một biểu đồ và muốn thêm một chú giải với ba màu được sử dụng. Đây là mã được sử dụng

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

và đầu ra

ggplot ba dòng

Tôi muốn thêm một huyền thoại với ba màu được sử dụng và tên của biến (TempMax, TempMedia và TempMin). Tôi đã thử

scale_colour_manual

nhưng không thể tìm ra cách chính xác.

Thật không may, dữ liệu gốc đã bị xóa khỏi trang web được liên kết và không thể phục hồi. Nhưng chúng đến từ các tệp dữ liệu meteo với định dạng này

"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

Tôi vẫn tò mò những huyền thoại thời tiết có thể được gắn với các yếu tố riêng biệt của cốt truyện (chẳng hạn như geom_line khác nhau).
Etienne Low-Décarie

Nếu bạn chỉ có 3 dòng tôi khuyên bạn nên xem gói dirrectlabels. (LINK)
Tyler Rinker

@TylerRinker Tôi đã sử dụng nó trước đây cho các mục đích khác nhưng bây giờ câu trả lời từ csgillespie hoạt động tốt hơn đối với tôi
pacomet

@ EtienneLow-Décarie Bạn có thể, nhưng nói chung chỉ khi họ sử dụng thẩm mỹ khác nhau. ví dụ: ánh xạ một tập hợp các dòng thành màu và một bộ khác thành linetype. Thông thường, bạn sẽ chuyển dữ liệu riêng cho từng geom trong trường hợp đó.
joran

Câu trả lời:


82

Tôi có xu hướng thấy rằng nếu tôi chỉ định các màu riêng lẻ trong nhiều geom, thì tôi đã làm sai. Đây là cách tôi sẽ vẽ dữ liệu của bạn:

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

Tất cả chỉ còn lại là một lệnh ggplot đơn giản:

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

Ví dụ cốt truyện

nhập mô tả hình ảnh ở đây


87
Tôi vẫn tò mò về cách thêm các huyền thoại liên quan đến việc thêm các yếu tố riêng biệt như geom_line, mà tôi mặc dù đó là mục đích ban đầu của câu hỏi.
Etienne Low-Décarie

201

@Etienne đã hỏi cách thực hiện việc này mà không làm tan dữ liệu (nói chung là phương pháp ưa thích, nhưng tôi nhận ra có thể có một số trường hợp không thể thực hiện được), tôi trình bày phương án sau.

Bắt đầu với một tập hợp con của dữ liệu gốc:

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

Bạn có thể nhận được hiệu ứng mong muốn bằng cách (và điều này cũng dọn sạch mã âm mưu ban đầu):

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

Ý tưởng là mỗi dòng được cung cấp một màu bằng cách ánh xạ colourthẩm mỹ thành một chuỗi không đổi. Chọn chuỗi đó là những gì bạn muốn xuất hiện trong truyền thuyết là dễ nhất. Thực tế là trong trường hợp này, nó giống như tên của ybiến được vẽ là không đáng kể; nó có thể là bất kỳ tập hợp các chuỗi. Điều rất quan trọng là đây là trong aescuộc gọi; bạn đang tạo một ánh xạ tới "biến" này.

scale_colour_manualBây giờ có thể ánh xạ các chuỗi này đến các màu thích hợp. Kết quả là nhập mô tả hình ảnh ở đây

Trong một số trường hợp, ánh xạ giữa các mức và màu sắc cần được làm rõ bằng cách đặt tên các giá trị theo tỷ lệ thủ công (nhờ @DaveRGP để chỉ ra điều này):

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

(đưa ra con số tương tự như trước). Với các giá trị được đặt tên, các dấu ngắt có thể được sử dụng để đặt thứ tự trong chú giải và bất kỳ thứ tự nào cũng có thể được sử dụng trong các giá trị.

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


2
Tôi thích giải pháp này, nhưng tôi nghĩ có thể có một hạn chế. Có vấn đề sắp xếp chữ cái nào giữa việc ánh xạ các biến 'phá vỡ' và 'giá trị' không? TempM {a] x, TempM {e} dia và TempM {i} n sắp xếp gọn gàng, mặc dù khi tôi điều chỉnh tên này với tên biến của mình, các màu dường như được khớp theo thứ tự bảng chữ cái với 'break', không theo thứ tự đầu vào . Những điều trên có thể được làm rõ / tinh chỉnh để phản ánh / sửa lỗi này không?
DaveRGP

3
Tôi đã tìm cách khắc phục sự cố mà tôi đã mua trước đó: đặt hàng màu. sử dụng biểu mẫu scale_colour_manual("", values = c("TempMax" = "red", "TempMedia" = "green", "TempMin" = "blue"))trong đó TempMax, TempMedia và TempMin được chỉ định làm đối số màu như trong câu trả lời ở trên.
DaveRGP

@DaveRGP Nó có thể được coi là một lỗi của ggplot không?
Alessandro Jacopson

1
@StellaBerman Cảm ơn bạn. Thật tuyệt khi biết rằng câu trả lời này vẫn còn hữu ích (gần) 5 năm sau (!).
Brian Diggs

1
@BrianDiggs Bạn sẽ không biết làm thế nào để hiển thị dấu chấm này theo tỷ lệ trái ngược với một dòng phải không?
Stella Biderman

2

Tôi thực sự thích giải pháp được đề xuất bởi @Brian Diggs. Tuy nhiên, trong trường hợp của tôi, tôi tạo các ô dòng trong một vòng lặp thay vì cung cấp cho chúng một cách rõ ràng vì tôi không biết apriori sẽ có bao nhiêu lô. Khi tôi cố gắng điều chỉnh mã của @ Brian, tôi đã gặp một số vấn đề với việc xử lý màu sắc chính xác. Hóa ra tôi cần phải sửa đổi các chức năng thẩm mỹ. Trong trường hợp ai đó có cùng một vấn đề, đây là mã làm việc cho tôi.

Tôi đã sử dụng cùng một khung dữ liệu như @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")  

Trong trường hợp của tôi, tôi tạo my.colsmy.namesđộng, nhưng tôi không muốn làm cho mọi thứ trở nên phức tạp không cần thiết nên tôi cung cấp cho chúng rõ ràng ở đây. Ba dòng này làm cho việc sắp xếp các huyền thoại và gán màu dễ dàng hơn.

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

Và đây là cốt truyện:

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

nhập mô tả hình ảnh ở đây


2
Với sự phức tạp này, nó thực sự trở nên dễ dàng hơn nhiều khi chỉ định hình lại dữ liệu của bạn thành dạng dài ggplotmong đợi.
Axeman

1
Tôi không nghĩ nó thực sự tăng thêm độ phức tạp so với câu trả lời ban đầu được đăng bởi @Brian. Ngoài ra, một số người có thể muốn làm điều đó mà không cần định hình lại dữ liệu.
Justyna

... và cách tiếp cận này cho phép các địa chất khác nhau (loại cốt truyện) theo biến
mac
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.