首页 文章

如何使用ggplot2为geom_pointrange()类型图形获取图例键中的垂直线

提问于
浏览
2

UPDATE: The question is moot. The vertical lines in the legend key are now default for geom_pointrange() in ggplot2.

对于ggplot2图形,其具有用于点估计的符号,并且垂直线表示关于该估计的范围(95%置信区间,四分位数间距,最小值和最大值等),我无法获得图例键以显示具有 vertical 行 . 由于 geom_pointrange() 只有 yminymax 的参数,我认为 geom_pointrange(show_guide=T) 的预期(默认)功能是有垂直线(我说默认,因为我明白用 coord_flip 可以在图中制作水平线) . 我也明白,当图例位置向右或向左时,在图例键中有垂直线将有垂直线"run together" ...但对于顶部或底部的图例,通过符号的垂直线表示该键将匹配出现在情节中 .

然而,我尝试过的方法仍然在图例键中放置水平线:

## set up
library(ggplot2)
set.seed(123)
ru <- 2*runif(10) - 1
dt <- data.frame(x   = 1:10, 
                 y   = rep(5,10)+ru, 
                 ylo = rep(1,10)+ru, 
                 yhi = rep(9,10)+ru,
                 s   = rep(c("A","B"),each=5),
                 f   = rep(c("facet1", "facet2"), each=5))

默认 show_guide=T for geom_pointrange 产生所需的图,但在图例键中有水平线,需要垂直(以匹配图):

ggplot(data=dt)+
  geom_pointrange(aes(x     = x, 
                      y     = y, 
                      ymin  = ylo, 
                      ymax  = yhi, 
                      shape = s), 
                  size=1.1,
                  show_guide=T)+
  theme(legend.position="bottom")

enter image description here

同时使用 geom_pointgeom_segment 的尝试会产生所需的绘图,但在图例键中需要垂直的水平线(以匹配绘图):

ggplot(data=dt)+
  geom_point(aes(    x = x, 
                     y = y, 
                 shape = s), 
             size=3,
             show_guide=T)+
  geom_segment(aes(   x = x, 
                   xend = x, 
                      y = ylo, 
                   yend = yhi), 
               show_guide=T)+
  theme(legend.position="bottom")

enter image description here

一起尝试使用 geom_pointgeom_vline 会产生 desired legend key ,但不会尊重图中的 yminymax 值:

ggplot(data=dt)+
  geom_point(aes(x=x, y=y, shape=s), show_guide=T, size=3)+
  geom_vline(aes(xintercept=x, ymin=ylo, ymax=yhi ), show_guide=T)+
  theme(legend.position="bottom")

enter image description here

如何获取第3个图形的图例键,但前两个图形之一?

2 回答

  • 0

    我的解决方案涉及绘制一条带有 geom_vline(show_guide=T) 的垂直线,用于超出显示的x轴边界的x值以及绘制 geom_segment(show_guide=F)

    ggplot(data=dt)+
      geom_point(aes(x=x, y=y, shape=s), show_guide=T, size=3)+
      geom_segment(aes(x=x, xend=x, y=ylo, yend=yhi), show_guide=F)+
      geom_vline(xintercept=-1, show_guide=T)+
      theme(legend.position="bottom")+
      coord_cartesian(xlim=c(0.5,10.5))
    

    enter image description here

    coord_cartesian() 用于数字x轴的解决方案很好,但 facet_grid(scales='free_x') 可能有问题:

    # problem:  coord_cartesian with numeric x and facetting with scales=free_x
    ggplot(data=dt)+
      geom_point(aes(x=x, y=y, shape=s), show_guide=T, size=3)+
      geom_segment(aes(x=x, xend=x, y=ylo, yend=yhi), show_guide=F)+
      geom_vline(xintercept=-1, show_guide=T)+
      theme(legend.position="bottom")+
      coord_cartesian(xlim=c(0.5,10.5))+
      facet_grid(.~f, scales="free_x")
    

    enter image description here

    因此,在这种情况下,另一种解决方案可能不适用于所有情况,但将x值更改为某个有意义的因子字符,然后调整xlim:

    ## hack solution: adjust xlim after change x to factor or character 
    ## (carefully -- double check conversion):
    dt$x <- factor(dt$x)
    ggplot(data=dt)+
      geom_point(aes(x=x, y=y, shape=s), show_guide=T, size=3)+
      geom_segment(aes(x=x, xend=x, y=ylo, yend=yhi), show_guide=F)+
      geom_vline(xintercept=-1, show_guide=T)+
      theme(legend.position="bottom")+
      coord_cartesian(xlim=c(0.5,5.5))+
      facet_grid(.~f, scales="free_x")
    

    enter image description here

  • 2

    如果您不介意使用 grid 绘制绘图,则可以直接操作指南grobs:

    library(grid)
    library(gtable)
    library(ggplot2)
    
    set.seed(123)
    ru <- 2*runif(10) - 1
    dt <- data.frame(x   = 1:10, 
                     y   = rep(5,10)+ru, 
                     ylo = rep(1,10)+ru, 
                     yhi = rep(9,10)+ru,
                     s   = rep(c("A","B"),each=5),
                     f   = rep(c("facet1", "facet2"), each=5))
    
    ggplot(data=dt)+
      geom_pointrange(aes(x     = x, 
                          y     = y, 
                          ymin  = ylo, 
                          ymax  = yhi, 
                          shape = s), 
                      size=1.1,
                      show_guide=T)+
      theme(legend.position="bottom") -> gg
    
    gb <- ggplot_build(gg)
    gt <- ggplot_gtable(gb)
    
    seg <- grep("segments", names(gt$grobs[[8]]$grobs[[1]]$grobs[[4]]$children))
    gt$grobs[[8]]$grobs[[1]]$grobs[[4]]$children[[seg]]$x0 <- unit(0.5, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[4]]$children[[seg]]$x1 <- unit(0.5, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[4]]$children[[seg]]$y0 <- unit(0.1, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[4]]$children[[seg]]$y1 <- unit(0.9, "npc")
    
    seg <- grep("segments", names(gt$grobs[[8]]$grobs[[1]]$grobs[[6]]$children))
    gt$grobs[[8]]$grobs[[1]]$grobs[[6]]$children[[seg]]$x0 <- unit(0.5, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[6]]$children[[seg]]$x1 <- unit(0.5, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[6]]$children[[seg]]$y0 <- unit(0.1, "npc")
    gt$grobs[[8]]$grobs[[1]]$grobs[[6]]$children[[seg]]$y1 <- unit(0.9, "npc")
    
    grid.newpage()
    grid.draw(gt)
    

    enter image description here

相关问题