【问题标题】:Look of arrows in ggplot2 geom_segment()ggplot2 geom_segment() 中的箭头
【发布时间】:2015-04-06 09:19:30
【问题描述】:

我正在尝试在 ggplot2 中绘制一个带有箭头的图,看起来像这样,它是使用基础 R 图形制作的。 (颜色不重要)

使用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)  )

我明白了:

问题是箭头看起来不对(因为它们看起来不像第一个图)。使用 geom_segment() 并不重要。

这个问题可能会给出答案,但我希望有一些不那么老套的东西: Specifying gpar settings for grid arrows in R

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    更新: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'))
    

    如果绘图在您当前的窗口中,您可以直接编辑箭头的形状

    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)
    

    【讨论】:

    • 是否可以让第二个箭头自动从第一个箭头结束的地方开始,还是我必须以某种方式手动执行?
    • 我不认为这可以很容易地做到拉斯穆斯。如果您注意到箭头的末端超出了实际的 xend 位置,但超出多少(以原生比例)取决于绘图的宽度。所以很难为第二个箭头指定一个起始位置(如果有人可以展示如何做会很棒)。也许,一个快速的解决方法是反转级别,使第二个箭头位于第一个/的下方?
    • @user20650 不幸的是,您的非常好的答案似乎不再适用于ggplot 2.2.0。如果您有任何时间和可能性来更新您的答案,我们将不胜感激。提前致谢。
    • @Henrik ;哦,又一次,这很烦人。弄乱杂物的答案并不能真正经受住时间的考验!你能试试吗:grid.force() 似乎可以解决问题:很遗憾它是如此互动
    • @Henrik ;好的,我在 Windows 上试过了,是的,箭头的底部没有正确绘制:使用操作代码或在编辑 grob 时。 [我尝试更新 geom_segment 函数以获取 linejoin 参数here,它适用于 ubuntu,但问题仍然存在于 windows 上)
    【解决方案2】:

    挑战似乎是,如果在geom_segment 块中调用size,则网格包中的箭头构造函数会变得混乱。

    所以

    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 参数。

    【讨论】:

      猜你喜欢
      • 2020-04-07
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多