2015-04-06 279 views
27

我試圖用ggplot2中的箭頭繪製一個情節,看起來像這樣,這是使用基本的R圖片製作的。 (顏色並不重要)ggplot2中的箭頭geom_segment()

enter image description here

使用GGPLOT2:

library(ggplot2) 
library(scales) 
library(grid) 


df3 <- structure(list(value1 = c(51L, 57L, 59L, 57L, 56L, 56L, 60L, 
66L, 61L, 61L), value2 = c(56L, 60L, 66L, 61L, 61L, 59L, 61L, 
66L, 63L, 63L), group = c("A", "B", "C", "D", "E", "A", "B", 
"C", "D", "E"), time = c("1999", "1999", "1999", "1999", "1999", 
"2004", "2004", "2004", "2004", "2004"), y_position = c(1L, 2L, 
3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L)), .Names = c("value1", "value2", 
"group", "time", "y_position"), row.names = c(NA, -10L), class = "data.frame") 




ggplot(df3, aes(x = value1, y = y_position, group = time, color = time)) + 

geom_segment(x = min(df3$value1, df3$value2), xend = max(df3$value1, df3$value2), 
       aes(yend = y_position), color = "lightgrey", size = 19) + 


scale_y_continuous( labels = df3$group, breaks = df3$y_position) + 

theme_classic() + theme(axis.line = element_blank(), axis.title = element_blank() ) + 

geom_segment(aes(yend = y_position, xend = value2, color = time, group = time), size = 19, alpha = 0.9, 

       arrow = arrow(length = unit(40, "points"),type = "closed", angle = 40) ) 

我得到這個:

enter image description here

的問題是,箭頭看上去是錯誤的(因爲它們看起來不像第一個情節)。使用geom_segment()並不重要。

這個問題可以給出答案,但我希望少哈克的東西: Specifying gpar settings for grid arrows in R

回答

17

更新:GGPLOT2 v2.1.0.9001

如果情節是在當前窗口,您可以編輯形狀直接的箭頭與

grid.force() 
# change shape of arrows 
grid.gedit("segments", gp=gpar(linejoin ='mitre')) 
# change the shape in legend also 
grid.gedit("layout", gp=gpar(linejoin ='mitre')) 

。如果情節是在當前的窗口中,您可以編輯直接箭頭的形狀LY與

grid.gedit("segments", gp=gpar(linejoin ='mitre')) 

ggplot現在似乎已經改變了傳說鍵箭頭形狀,所以如果你想改變這些的形狀,以及,你可以用

grid.gedit("gTableParent", gp=gpar(linejoin ='mitre')) 
做到這一點在整個劇情

原來的答案

不低於哈克,但也許更容易?您可以編輯由ggplotGrob返回的grobs。

如果p是你的陰謀:

g <- ggplotGrob(p) 

idx <- grep("panel", g$layout$name) 

nms <- sapply(g$grobs[[idx]]$children[[3]]$children , '[[', "name") 

for(i in nms) { 
    g$grobs[[idx]]$children[[3]] <- 
       editGrob(g$grobs[[idx]]$children[[3]], nms[i], 
         gp=gpar(linejoin ='mitre'), grep=TRUE) 
} 

grid.newpage() 
grid.draw(g) 

enter image description here

+0

是否有可能使第二個箭頭從第一個箭頭結束時自動開始,還是必須以某種方式手動執行? – 2015-04-20 07:13:09

+0

我不認爲這可以輕鬆完成Rasmus。如果您注意到箭頭的結束超出了實際的xend位置,但超出範圍(以原生比例)取決於圖的寬度。所以很難爲第二個箭頭指定一個開始位置(如果有人能夠顯示的話,會很棒)。也許,一個快速的解決辦法是扭轉水平,所以第二個箭頭在第一個/下面。 – user20650 2015-04-22 08:59:15

+0

@ user20650不幸的是,似乎你的答案不再適用於'ggplot 2.2.0'。如果您有任何時間和可能性更新您的答案,它將不勝感激。提前致謝。 – Henrik 2016-11-25 15:57:58

5

所面臨的挑戰似乎是從電網包裝箭頭構造函數將被搞砸了,如果sizegeom_segment塊調用。

所以

p <- ggplot(df3) + coord_flip() 

p1 <- p + geom_bar(aes(x=group,y=max(c(value1,value2))*1.1),width=0.2, stat="identity",position="identity",alpha=0.2) 

df1<-filter(df3,time=="1999") 

p1 + geom_segment(data=df1,aes(x=group,xend=group,y=value1,yend=value2),color="blue",size=8,arrow=arrow(angle=20,type="closed",ends="last",length=unit(1,"cm"))) 

爲您展示看起來可笑。我嘗試的段分離爲只是一個脂肪鏈段的解決方法和像這樣在瘦段的箭頭(兩層):

p2<-p1 + geom_segment(data=df1,aes(x=group,xend=group,y=value1,yend=value2), color="blue",arrow=arrow(angle=20,type="closed",ends="last",length=unit(1,"cm"))) 

p2 + geom_segment(data=df1,aes(x=group,xend=group,y=value1,yend=value2), color="blue",size=8) 

但現在的脂肪段到底是不是斜接,因此掩蓋了箭頭。

修復arrow參數似乎是需要的。