I have a three-panel display in ggplot2. The panels are arranged vertically one on top of the other.

I am trying to add three vertical lines that cross the panels. In other words, the vertical lines should not be clipped to the plotting regions. Here's what I want:

enter image description here

However, when I use the built-in ggplot2::geom_hline() (since the coordinates are flipped on this plot), I get this:

enter image description here

After consulting previous solutions (here and here, for example), I decided to try solutions that use gtable to modify the plot layout and/or add extra grobs using gtable_add_grob.

I've tried using gtable_add_grob in conjunction with either a combination of moveToGrob and lineToGrob (here) or segmentsGrob (here), but neither have solved my issue. moveToGrob and lineToGrob seems to only work with a single vertical line and I want multiple; segmentsGrob seems to get applied to only a single plotting region.

I'm pretty confused at this point. Anyone have any advice?

DATA

reprex <- data.frame(
     diff = c(1.31662094999948, 0.866821096444503, 1.51890736785243,
              2.38852458319537, 1.50276154671547, 1.58942354388551,
              0.579285478632874, 0.705737525937795, 0.820822837588395,
              0.803116467811481, 1.22496342202883, 0.65562485652129, 8.95737110367273,
              0.489705699642001, 18.291335204432, 1.32585187406239,
              0.423474055403873, 3.13089280711167, 0.642914242106793, 0.777062294322688,
              0.827365124783434, 1.79046662862126, 1.18259455819337,
              1.51401561610137, 0.328081138137496, 1.72740789953949,
              0.189926848328619, 1.45456392298709, 0.905411049427828, 1.60652327349693,
              1.81017750948238, 1.34335500622466, 1.34750494180214,
              0.722144243864773, 0.963665848513251, 0.749372041127016, 0.714812829735733,
              0.902315301989547, 0.792198501077858, 19.892119154905,
              1.75845439073389, 11.3122747224641, 2.74831540769519, 0.969397798638758,
              2.83507494194274, 0.658301650479607, 0.819696564064323,
              0.803104074531595, 1.34654008741793, 0.925244768606367,
              1.45533391066467, 0.24199160083309, 0.991764875430923, 0.244000979292541,
              1.19499450951635, 0.797225062653057, 1.49894247621815,
              2.41249071570669, 1.48095400287587, 1.62901123939155, 0.800939314874935,
              1.00449220172611, 0.797357424476374, 0.603543063256566,
              0.900713546848067, 0.670072150428499, 29.3000907867695,
              1.81141098721977, 16.1752860027313, 1.94316437225496, 0.650354223810153,
              2.98785538882299, 0.517693257397596, 0.606327251215883,
              0.853818224992284, 2.19310287140208, 1.50701879957261, 1.45525913281509,
              0.212947121365625, 1.0411346565884, 0.204533697940102),
       lb = c(0.492454940483492, 0.339355619743384, 0.957348434323997,
              1.26044791901582, 0.844261377268072, 1.09110321652908,
              0.322705783295933, 0.415474890828733, 0.583295860864908,
              0.451122506616931, 0.729128070092705, 0.467566913587157, 2.78767229589579,
              0.14257769192107, 9.50350595115945, 0.577593901163453,
              0.190917776501861, 1.84466415977226, 0.35956473247075,
              0.457078546874678, 0.599890772825811, 0.578883702093973, 0.402412042012875,
              0.820368078181714, 0.17260752641746, 0.927458567625053,
              0.131153965856016, 0.615148567644514, 0.407648792438177,
              0.932285544146073, 1.03364348457678, 0.826087466195112, 0.897205256605993,
              0.4275157755967, 0.612992386963926, 0.511383739399791,
              0.428874429875268, 0.583105952158013, 0.542148907801877, 4.43826058874205,
              0.372974670653646, 5.40020940786844, 1.14206113589909,
              0.422048214601624, 1.56677388916208, 0.397809279336784,
              0.528064920170086, 0.561512990408551, 0.458191509483684, 0.340370706390903,
              0.721212596438438, 0.125077100435655, 0.526945268441644,
              0.160890120433013, 0.361795965773801, 0.250825296360952,
              0.943872992434227, 1.15365773535204, 0.747771285996631, 1.12039094496198,
              0.409936729464542, 0.539876902216984, 0.567250295904343,
              0.313988141767326, 0.492823474852442, 0.479070611433729,
              3.90299786822159, 0.233618126135971, 8.62862044975527, 0.720592578735177,
              0.248713293467573, 1.77546875882829, 0.257921470181596,
              0.315074709151686, 0.619835605030249, 0.543099639646348,
              0.390664978249036, 0.792229860646373, 0.0958528256717599, 0.477302677009191,
              0.142069312041543),
       ub = c(3.52010018272045, 2.21413399256342, 2.40986406766882,
              4.52620818239219, 2.67487335923648, 2.31533292504986,
              1.03986876940221, 1.19878593510989, 1.15507442433696, 1.4297581065218,
              2.05798603408287, 0.919320721799612, 28.7818970712727,
              1.68197190619848, 35.2052121901469, 3.04345871452908,
              0.939306328022599, 5.31396987234459, 1.14955301612451, 1.32105480203952,
              1.14109614735927, 5.53784937563499, 3.47536788927362,
              2.7941644083463, 0.623595247760335, 3.21732760422109, 0.27503710986249,
              3.43942312042942, 2.01096920592577, 2.76837611018766,
              3.17008975021737, 2.18451767711803, 2.02380620801309, 1.21982003639318,
              1.51494845179116, 1.0981155886614, 1.191391572828, 1.39626923922028,
              1.1575758174161, 89.1557394076067, 8.2905411213909,
              23.6967772416461, 6.6136893575566, 2.22659890385437, 5.13006374565649,
              1.08936891504055, 1.27238608639718, 1.1486397742285,
              3.95723222603287, 2.51513384013216, 2.93671630527504, 0.468190697336216,
              1.86660290365135, 0.370044336690687, 3.94700884715508,
              2.53390630747049, 2.38043525455315, 5.04492040838695, 2.93301548174711,
              2.36852826238615, 1.5648848712587, 1.86895305056603,
              1.12080833973652, 1.16012097512602, 1.64619774599523, 0.937224442626833,
              219.957926982961, 14.0451848445645, 30.3223300635011,
              5.23997594345012, 1.70059513317832, 5.02812554719921, 1.03910042295524,
              1.16681131455086, 1.17612727538199, 8.85601803691856,
              5.81343552330794, 2.67318773103787, 0.473084399756679, 2.2710146524667,
              0.294462139584516),
     xmin = c(5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 2, 2, 2, 3, 3, 3, 0, 0,
              0, 4, 4, 4, 1, 1, 1, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 2,
              2, 2, 3, 3, 3, 0, 0, 0, 4, 4, 4, 1, 1, 1, 5, 5, 5, 6, 6, 6, 7,
              7, 7, 8, 8, 8, 2, 2, 2, 3, 3, 3, 0, 0, 0, 4, 4, 4, 1, 1, 1),
     xmax = c(6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 3, 3, 3, 4, 4, 4, 1, 1,
              1, 5, 5, 5, 2, 2, 2, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 3,
              3, 3, 4, 4, 4, 1, 1, 1, 5, 5, 5, 2, 2, 2, 6, 6, 6, 7, 7, 7, 8,
              8, 8, 9, 9, 9, 3, 3, 3, 4, 4, 4, 1, 1, 1, 5, 5, 5, 2, 2, 2),
     ymin = c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
              2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
     ymax = c(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
              3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
              2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
      var = as.factor(c("18 - 29", "18 - 29", "18 - 29", "30 - 44",
                        "30 - 44", "30 - 44", "45 - 59", "45 - 59",
                        "45 - 59", "60 +", "60 +", "60 +", "Black", "Black",
                        "Black", "Hispanic", "Hispanic", "Hispanic", "Male", "Male",
                        "Male", "Other", "Other", "Other", "White", "White",
                        "White", "18 - 29", "18 - 29", "18 - 29", "30 - 44",
                        "30 - 44", "30 - 44", "45 - 59", "45 - 59",
                        "45 - 59", "60 +", "60 +", "60 +", "Black", "Black", "Black",
                        "Hispanic", "Hispanic", "Hispanic", "Male", "Male",
                        "Male", "Other", "Other", "Other", "White", "White",
                        "White", "18 - 29", "18 - 29", "18 - 29", "30 - 44",
                        "30 - 44", "30 - 44", "45 - 59", "45 - 59",
                        "45 - 59", "60 +", "60 +", "60 +", "Black", "Black", "Black",
                        "Hispanic", "Hispanic", "Hispanic", "Male", "Male",
                        "Male", "Other", "Other", "Other", "White", "White",
                        "White")),
   comparison = as.factor(c("Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3",
                        "Comparison 1", "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1",
                        "Comparison 2", "Comparison 3", "Comparison 1", "Comparison 2",
                        "Comparison 3", "Comparison 1")),
      sig = as.factor(c("Non-significant", "Non-significant",
                        "Non-significant", "Less prevalent & significant",
                        "Non-significant", "Less prevalent & significant",
                        "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "More prevalent & significant", "Less prevalent & significant",
                        "Non-significant", "Less prevalent & significant",
                        "Non-significant", "More prevalent & significant",
                        "Less prevalent & significant", "Non-significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "More prevalent & significant", "Non-significant",
                        "More prevalent & significant", "Non-significant", "Non-significant",
                        "Non-significant", "Less prevalent & significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "Less prevalent & significant", "Non-significant",
                        "Less prevalent & significant", "Less prevalent & significant",
                        "Non-significant", "Less prevalent & significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "Non-significant", "More prevalent & significant", "Non-significant",
                        "More prevalent & significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "Less prevalent & significant", "Non-significant",
                        "Less prevalent & significant", "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "Non-significant", "More prevalent & significant",
                        "Less prevalent & significant", "Non-significant",
                        "Less prevalent & significant", "Non-significant", "Non-significant",
                        "Less prevalent & significant", "Non-significant",
                        "Non-significant", "Non-significant", "Non-significant",
                        "Non-significant", "Non-significant",
                        "More prevalent & significant", "Non-significant",
                        "More prevalent & significant")),
   sample = as.factor(c("Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No",
                        "Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No",
                        "Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No",
                        "Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No",
                        "Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No", "Yes/No",
                        "Yes/No", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Quantitative",
                        "Quantitative", "Quantitative", "Strict", "Strict", "Strict",
                        "Strict", "Strict", "Strict", "Strict", "Strict",
                        "Strict", "Strict", "Strict", "Strict", "Strict", "Strict",
                        "Strict", "Strict", "Strict", "Strict", "Strict",
                        "Strict", "Strict", "Strict", "Strict", "Strict",
                        "Strict", "Strict", "Strict")))

BASIC GGPLOT

p <- ggplot(reprex, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)) +
  geom_rect(color="white", aes(fill=sig, alpha=abs(log(diff)))) + 
  scale_fill_manual(values=c("green", "grey", "red")) +
  scale_x_continuous(breaks=1:length(levels(plot_dat$var)) - .75, labels=levels(plot_dat$var), expand=c(0, 0)) +
  scale_y_continuous(breaks=1:length(levels(plot_dat$sample)) - .5, labels=levels(plot_dat$sample), expand=c(0, .0)) +
  facet_grid(rows=vars(comparison)) +
  theme_minimal(base_size=20) + 
  theme(panel.grid=element_blank(), legend.title=element_blank(), axis.text.x=element_text(angle=90, hjust=1), strip.text=element_text(size=12))

SEGMENTSGROB ATTEMPT

gb <- ggplot_build(p)
g <- ggplot_gtable(gb)

xs <- c(1, 5)/length(unique(reprex$var))

g <- gtable_add_grob(g, 
                     list(segmentsGrob(x0=xs, x1=xs, y0=0, y1=1),
                          segmentsGrob(x0=xs, x1=xs, y0=0, y1=1),
                          segmentsGrob(x0=xs, x1=xs, y0=0, y1=1),
                          segmentsGrob(x0=xs, x1=xs, y0=0, y1=1)), 
                     clip="off", t=c(7, 9, 11, 14), l=5)

grid.newpage()
grid.draw(g)

MOVETOGROB AND LINETOGROB ATTEMPT

gb <- ggplot_build(p)
g <- ggplot_gtable(gb)

xs <- c(1, 5)/length(unique(reprex$var))

for(i in xs) {
  g <- gtable_add_grob(g, moveToGrob(i, 1), clip="off", t=7, l=5)
  g <- gtable_add_grob(g, lineToGrob(i, 0), clip="off", t=14, l=5)
}

grid.newpage()
grid.draw(g)

1 Answers

2
Community On Best Solutions
g <- gtable_add_grob(g, segmentsGrob(x0=xs, x1=xs, y0=0, y1=1), 
                     t=7, b=14, l=5)

g$layout$clip <- 'off'