在ggplot2中的图例上的某些级别之间添加线条

EBW*_*EBW 5 r legend ggplot2

我有一个这样的情节:

我的示例情节

这是一个马赛克图,其中一些组上方有一条黑线.我希望黑线也能成为传奇.在这个例子中,图例有6个级别,高于2级和4级的正方形,我想要一条黑线.

我尝试了类似的方法: 如何在ggplot2中绘制绘图区域以外的线条,但不幸的是,当我调整绘图大小时,线条会随着情节移动而不是传说,它们会在错误的位置移动.

以下是制作上图的示例代码.

exampledata<-data.frame(var1Center=c(rep(.2, 6) ,rep(.5,6) ,rep(.8,6)), 
                        var2Height=c(.2,.2,.2,.1,.1,.2, .1,.1,.05,.45,.1,.2,  .4,.07,.03,.1,.35,.05),
                        var1=c(rep("Thing 1", 6), rep("Thing 2", 6), rep("Thing 3", 6)),
                        var2=c( rep(c("A", "B", "C","D", "E", "F"), 3)), 
                        marginVar1=c(rep(.4,6) ,rep(.2,6), rep(.4,6)))

plotlines<-data.frame(xstart=c(0, 0,.4, .4, .6,.6), xstop=c(.4,.4, .6,.6, 1,1), value=c(.4, .7, .2,.7, .47, .6))

ggplot(exampledata, aes(var1Center, var2Height)) +
  geom_bar(stat = "identity", aes(width = marginVar1, fill = var2)) +
  scale_x_continuous(breaks=exampledata$var1Center, labels=exampledata$var1, expand=c(0,0))+
  theme_bw()+scale_y_continuous(name="Proportion",expand=c(0,0))+
  guides(fill = guide_legend(reverse=TRUE))+
  theme(panel.border=element_blank(), panel.grid=element_blank())+
  theme(axis.text.x=element_text(angle=90, hjust=1, vjust=.3))+
  geom_segment(data=plotlines, aes(x=xstart, xend=xstop, y=value, yend=value))
Run Code Online (Sandbox Code Playgroud)

osh*_*hun 3

这是一个编辑图例 grob 的解决方案。*我在下面添加了一个更长的答案,它展示了如何检查 grob 结构以帮助查找可以编辑的属性。

*我只是在学习grob,所以如果有人有关于如何添加linesGrob()到图例的解决方案,我很乐意看到它。

简短回答

p1 <- ggplot()... #Your original plot

gt <- ggplotGrob(pl)  #Convert plot to grob
library(gtable); library(gridExtra)
leg <- gtable_filter(gt, "guide-box")  #Extract the legend

#Modify the legend by adding a black line that is horizontal y = c(1,1)
#sub-grob 8 is the teal box D
  leg$grobs[[1]]$grobs[[1]]$grobs[[8]]$children[[2]]$gp$col <- "black"
  leg$grobs[[1]]$grobs[[1]]$grobs[[8]]$children[[2]]$y <- unit(c(1,1), "npc")
#sub-grob 12 is the brown box B
  leg$grobs[[1]]$grobs[[1]]$grobs[[12]]$children[[2]]$gp$col <- "black"
  leg$grobs[[1]]$grobs[[1]]$grobs[[12]]$children[[2]]$y <- unit(c(1,1), "npc")

#Plot first plot with no legend, then add modified legend.
p2 <- grid.arrange(p1 +theme(legend.position = "none"), leg,
                   ncol = 2,
                   widths = unit.c(unit(1, "npc") - sum(leg$width), sum(leg$width)))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

更长的解释 Grob 的结构类似于列表,因此分别使用$[[]]来探索命名和未命名的列表元素。该str命令显示对象的结构

str(leg)
#List of 1
#$ grobs   :List of 1
#..$ :List of 1
#.. ..$ grobs   :List of 1
#.. .. ..$ 99_df28f764d4b38c6ac4aec87e00315c90:List of 20
#.. .. .. ..$ grobs   :List of 20    #<--Here is where we can find the legend boxes
#.. .. .. .. ..$ :List of 10
#.. .. .. .. .. ..$ x     :Class 'unit'  atomic [1:1] 0.5
#.. .. .. .. .. .. .. ..- attr(*, "unit")= chr "npc"
#.. (snip)

#'leg' has a named element 'grobs' with an unnamed list (' :List of 1').
#The first element of this unnamed list has a named sub-element 'grobs'.
#  which itself contains an unnamed list.
#The next command goes down these branches of 'leg' to the sub-elements.

leg$grobs[[1]]$grobs[[1]]   #Elements of the legend are shown here
#TableGrob (10 x 6) "layout": 20 grobs
#z         cells       name                             grob
#1   1 ( 1-10, 1- 6) background rect[legend.background.rect.171]
#2   2 ( 2- 2, 2- 5)      title       text[guide.title.text.127]
#3   3 ( 4- 4, 2- 2) key-3-1-bg        rect[legend.key.rect.141]
#4   4 ( 4- 4, 2- 2)  key-3-1-1            gTree[GRID.gTree.142]
#5   5 ( 5- 5, 2- 2) key-4-1-bg        rect[legend.key.rect.146]
#6   6 ( 5- 5, 2- 2)  key-4-1-1            gTree[GRID.gTree.147]
#7   7 ( 6- 6, 2- 2) key-5-1-bg        rect[legend.key.rect.151]
#8   8 ( 6- 6, 2- 2)  key-5-1-1            gTree[GRID.gTree.152]
#9   9 ( 7- 7, 2- 2) key-6-1-bg        rect[legend.key.rect.156]
#10 10 ( 7- 7, 2- 2)  key-6-1-1            gTree[GRID.gTree.157]
#11 11 ( 8- 8, 2- 2) key-7-1-bg        rect[legend.key.rect.161]
#12 12 ( 8- 8, 2- 2)  key-7-1-1            gTree[GRID.gTree.162]
#13 13 ( 9- 9, 2- 2) key-8-1-bg        rect[legend.key.rect.166]
#14 14 ( 9- 9, 2- 2)  key-8-1-1            gTree[GRID.gTree.167]
#15 15 ( 4- 4, 4- 4)  label-3-3       text[guide.label.text.129]
#16 16 ( 5- 5, 4- 4)  label-4-3       text[guide.label.text.131]
#17 17 ( 6- 6, 4- 4)  label-5-3       text[guide.label.text.133]
#18 18 ( 7- 7, 4- 4)  label-6-3       text[guide.label.text.135]
#19 19 ( 8- 8, 4- 4)  label-7-3       text[guide.label.text.137]
#20 20 ( 9- 9, 4- 4)  label-8-3       text[guide.label.text.139]

#This table shows the structure of the legened, 
#  where cells indicate (min.X-max.X, min.Y-max.Y).
#The 8th element is one of the color keys as a gTree grob.

#Examining this legend key box in more detail:
leg$grobs[[1]]$grobs[[1]]$grobs[[8]]$children
#(rect[GRID.rect.153], lines[GRID.lines.154]) 

#'children' is composed 2 sub-elements (in an unnamed list): rectangle and lines.
#Exploring second sub-element (lines):

#Line properties
str(leg$grobs[[1]]$grobs[[1]]$grobs[[8]]$children[[2]])
#List of 6
#$ x    :Class 'unit'  atomic [1:2] 0 1
#.. ..- attr(*, "unit")= chr "npc"
#.. ..- attr(*, "valid.unit")= int 0
#$ y    :Class 'unit'  atomic [1:2] 0 1
#.. ..- attr(*, "unit")= chr "npc"
#.. ..- attr(*, "valid.unit")= int 0
#$ arrow: NULL
#$ name : chr "GRID.lines.154"
#$ gp   :List of 4
#..$ col    : logi NA
#..$ lwd    : num 1.42
#..$ lineend: chr "butt"
#..$ lty    : num 1
#..- attr(*, "class")= chr "gpar"
#$ vp   : NULL
#- attr(*, "class")= chr [1:3] "lines" "grob" "gDesc"

#Here we see the line goes left-right with $x = c(0,1) and top bottom with $y = c(0,1).
# i.e. a bottom-left to top-right diagonal line.
#This line is not actually plotted because it has no color: $gp$col = NA

grid.draw(leg)  #Show the legend

#y and gp$col are changed as noted above.  
Run Code Online (Sandbox Code Playgroud)