2012-06-20 39 views
22

Dưới đây là số liệu:Làm cách nào để vẽ một mũi tên trên biểu đồ được vẽ bằng ggplot2?

set.seed(123) 
    myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50,30)) 
    require(ggplot2) 
    m <- ggplot(myd, aes(x = yvar)) 
    p <- m + geom_histogram(colour = "grey40", fill = "grey40", binwidth = 10) + 
     facet_wrap(~class) + theme_bw() 
    p + opts(panel.margin=unit(0 ,"lines")) 

Tôi muốn thêm nhãn để thanh mà mỗi lớp đối tượng rơi vào và tạo ra một cái gì đó như sau powerpoint đồ thị xử lý. Có cách nào để làm điều này trong R? ......

Edit: chúng ta có thể nghĩ đến con trỏ khác nhau như dấu chấm hoặc lỗi thanh, nếu mũi tên phải là không thể

enter image description here

Hãy nói rằng sau đây là đối tượng để được dán nhãn:

class name  yvar 
2  subject4 104.0 
3  subject3 8.5 
3  subject1 80.0 
4  subject2 40.0 
4  subject1 115.0 

classd <- data.frame (class = c(2,3,3,4,4), 
name = c ("subject4", "subject3", "subject1", "subject2", "subject1"), 
yvar = c(104.0, 8.5,80.0,40.0, 115.0)) 
+0

Bạn chắc chắn có thể thêm mũi tên giống như những người từ bên trong ggplot, nhưng bạn sẽ phải cụ thể hơn. Bạn có thể cung cấp một số dữ liệu mẫu về các chủ đề mà sẽ cho phép bạn xác định thanh họ sẽ rơi vào? – joran

+0

@joran Ok Tôi đã thêm dữ liệu mẫu nhờ – jon

Trả lời

15

Cập nhậtopts bị phản đối; sử dụng theme để thay thế.

Mở rộng phản hồi của bdemarest một chút, tôi nghĩ điều này sẽ tính toán chiều cao thanh theo chương trình. Hai cột cuối cùng của arrow_pos chứa thông tin có liên quan: Freq là chiều cao của thanh; xval ở vị trí x của điểm giữa của thanh. Nhưng vẫn còn, một số nhãn chồng chéo lên các thanh.

EDIT Theo mặc định cut tiếp giáp khoảng của nó như là (b1, b2], trong khi nó appeas rằng ggplot2 tiếp giáp khoảng của nó trong geom_histogram như [b1, b2). Tôi đã sửa đổi mã để cả hai ràng buộc khoảng cách của họ là [b1, b2), tức là cách ggplot.

library(ggplot2) 
library(grid) # unit() is in the grid package. 
library(plyr) # Data restructuring 

set.seed(123) 
myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50, 30)) 

arrow_pos = read.table(header=TRUE, stringsAsFactors=FALSE, 
         text="class name  yvar 
          2  subject4 104.0 
          3  subject3 8.5 
          3  subject1 80.0 
          4  subject2 40.0 
          4  subject1 115.0") 

# Calculate the y positions for the labels and arrows 
# For the myd data frame, obtain counts within each bin, but separately for each class 
bwidth <- 10 # Set binwidth 
Min <- floor(min(myd$yvar)/bwidth) * bwidth 
Max <- ceiling(max(myd$yvar)/bwidth) * bwidth 

# Function to do the counting 
func <- function(df) { 
    tab = as.data.frame(table(cut(df$yvar, breaks = seq(Min, Max, bwidth), right = FALSE))) 
    tab$upper = Min + bwidth * (as.numeric(rownames(tab))) 
    return(tab) 
    } 

# Apply the function to each class in myd data frame 
TableOfCounts <- ddply(myd, .(class), function(df) func(df)) 

# Transfer counts of arrow_pos 
arrow_pos$upper <- (floor(arrow_pos$yvar/bwidth) * bwidth) + bwidth 
arrow_pos <- merge(arrow_pos, TableOfCounts, by = c("class", "upper")) 
arrow_pos$xvar <- (arrow_pos$upper - .5 * bwidth)  # x position of the arrow is at the midpoint of the bin 
arrow_pos$class=factor(as.character(arrow_pos$class), 
    levels=c("1", "2", "3", "4")) # Gets rid of warnings. 

ggplot(myd, aes(x=yvar)) + 
    theme_bw() + 
    geom_histogram(colour="grey70", fill="grey70", binwidth=bwidth) + 
    facet_wrap(~ class) + 
    theme(panel.margin=unit(0, "lines")) + 
    geom_text(data=arrow_pos, aes(label=name, x=xvar, y=Freq + 2), size=4) + 
    geom_segment(data=arrow_pos, 
        aes(x=xvar, xend=xvar, y=Freq + 1.5, yend=Freq + 0.25), 
        arrow=arrow(length=unit(2, "mm"))) 

enter image description here

17

đây là giải pháp phần sử dụng geom_text() để thêm nhãn và geom_segment() với arrow tùy chọn để thêm mũi tên.

Hạn chế là tôi phải tự chọn vị trí y cho mỗi mũi tên và nhãn. Có thể ai đó khác có thể giúp tìm ra cách lập trình tìm chiều cao thanh biểu đồ.

set.seed(123) 
myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50,30)) 

library(ggplot2) 
library(grid) # unit() is in the grid package. 

arrow_pos = read.table(header=TRUE, stringsAsFactors=FALSE, 
         text="class name  yvar 
          2  subject4 104.0 
          3  subject3 8.5 
          3  subject1 80.0 
          4  subject2 40.0 
          4  subject1 115.0") 

arrow_pos$y = c(3, 5, 9, 13, 1) # Manually enter y position. 
arrow_pos$class = factor(as.character(arrow_pos$class), 
    levels=c("1", "2", "3", "4")) # Gets rid of warnings. 

p1 = ggplot(myd, aes(x=yvar)) + 
    theme_bw() + 
    geom_histogram(colour="grey40", fill="grey40", binwidth=10) + 
    facet_wrap(~ class) + 
    opts(panel.margin=unit(0 ,"lines")) + 
    geom_text(data=arrow_pos, aes(label=name, x=yvar, y=y + 2), size=3) + 
    geom_segment(data=arrow_pos, 
        aes(x=yvar, xend=yvar, y=y + 1.5, yend=y + 0.25), 
        arrow=arrow(length=unit(2, "mm"))) 

png("p1.png", height=600, width=600) 
print(p1) 
dev.off() 

enter image description here

+0

cảm ơn bạn, tôi ước tôi có thể chấp nhận câu trả lời của bạn vì bạn là người đầu tiên trả lời và bắt đầu ý tưởng, tuy nhiên để trả lời nhanh câu trả lời nào là câu trả lời hoàn hảo (như chiều cao). câu trả lời thứ hai ... nhưng xứng đáng với mã thông báo đánh giá cao – jon

+2

Tôi rất sẵn lòng trợ giúp! Tôi đồng ý rằng @Sandy Muspratt xứng đáng nhận được tín dụng cho giải pháp đầy đủ. – bdemarest

Các vấn đề liên quan