I'm trying to make a "forest" plot using the ggplot2 package, patchwork, and grid package. The only visual element that I could not add to my current plot is a vertical line over both of the figures. Any help is appreciated.
I'm wondering how I can do this trick.
codes are here -- you'll need to load tidyverse, patchwork, and grid packages.
library(tidyverse)
library(patchwork)
library(grid)
df2 = data.frame(gender = c("male", "female"), age = c("teenager", "adult"), math = rnorm(100,0,0.3))
df2 = df2 %>% mutate(math = if_else(age == "adult", math+0.2, math))
p1 = df2 %>%
ggplot(. , aes(x = gender, y = math)) +
stat_summary(fun.data = mean_cl_boot,geom = "errorbar") +
coord_flip() +
theme_minimal()+
theme(
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
p2 = df2 %>%
ggplot(. , aes(x = age, y = math)) +
stat_summary(fun.data = mean_cl_boot,geom = "errorbar") +
coord_flip() +
theme_minimal()+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
p1/p2
grid.draw(linesGrob()linesGrob(x = unit(c(0,1), "npc"), y = unit(c(0, 1), "npc")))
If I were you, I will do it via geom_hline
with facet
rather than grid.draw
because the value of x-axis = 0 in grob would change when you resize the plot.
library(tidyverse)
df2 = data.frame(gender = c("male", "female"), age = c("teenager", "adult"), math = rnorm(100,0,0.3))
df2 = df2 %>% mutate(math = if_else(age == "adult", math+0.2, math))
pivot_longer(df2, gender:age) |>
ggplot(aes(x = value, y = math)) +
stat_summary(fun.data = mean_cl_boot,geom = "errorbar") +
facet_grid(name~., space = "free", scale = "free", switch = "y") +
geom_hline(yintercept = 0, color = "darkslategray3") +
coord_flip() +
theme_minimal()+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.spacing.y = unit(-0.1, "lines"),
axis.title.y = element_blank(),
strip.placement = "outside"
)
The problem with your plot is that you want a vertical line, so the x
in linesGrob
should be a single value at x-axis = 0 rather than c(0, 1)
. You can play around with the value, currently I'm using x = 0.291
to get it at the right position.
library(dplyr)
library(ggplot2)
library(patchwork)
library(grid)
library(gridExtra)
df2 = data.frame(gender = c("male", "female"), age = c("teenager", "adult"), math = rnorm(100,0,0.3))
df2 = df2 %>% mutate(math = if_else(age == "adult", math+0.2, math))
p1 = df2 %>%
ggplot(. , aes(x = gender, y = math)) +
stat_summary(fun.data = mean_cl_boot,geom = "errorbar") +
coord_flip() +
theme_minimal()+
theme(
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
p2 = df2 %>%
ggplot(. , aes(x = age, y = math)) +
stat_summary(fun.data = mean_cl_boot,geom = "errorbar") +
coord_flip() +
theme_minimal()+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
p1/p2
grid.draw(linesGrob(x = 0.291, "npc", y = unit(c(0, 1), "npc"), gp = gpar(col = "darkslategray3")))