Skip to contents

The shape_plot() and forest_plot() functions return both a plot and the code used to generate plot (which will be shown in the RStudio Viewer pane). Examples of generated code are shown below.

Shape plot

my_results <- data.frame(
  x   = c(  12,   14, 15.5,   18),
  est = c(0.05, 0.21, 0.15, 0.32),
  se  = c(0.05, 0.05, 0.05, 0.05)
)

shape <- shape_plot(my_results,
                    xlims        = c(10, 20),
                    ylims        = c(0.75, 2),
                    exponentiate = TRUE,
                    printplot    = FALSE)

The code now stored in shape$code and shown in the RStudio Viewer pane is:

library(ggplot2)

datatoplot <- my_results

# Create the plot with main aesthetics
plot <- ggplot(datatoplot, aes(x = x, y = exp(est))) +

  # Plot the point estimates
  geom_point(aes(size   = 1),
             shape  = 15,
             colour = "black",
             fill = "black",
             stroke = 0.5) +
  
  # Plot point estimates text
  geom_text(aes(y     = exp(est+1.96*se),
                label = format(round(exp(est), 2), nsmall = 2)),
            vjust = -0.8,
            size  = 3.092846,
            colour = "black") +
  
  # Plot the CIs
  geom_linerange(aes(ymin = exp(est-1.96*se),
                     ymax = exp(est+1.96*se)),
                 linewidth = 0.5) +
  
  # Set the scale for the size of boxes
  scale_radius(guide  = "none",
               limits = c(0, NA_real_),
               range  = c(0, 3)) +
  
  # Use identity for aesthetic scales
  scale_shape_identity() +
  scale_colour_identity() +
  scale_fill_identity() +
  
  # Set the y-axis scale
  scale_y_continuous(trans = "log") +
  
  # Add titles
  xlab("Risk factor") +
  ylab("Estimate (95% CI)") +
  
  # Plot like a CKB plot
  ckbplotr::ckb_style(xlims          = c(10, 20),
                      ylims          = c(0.75, 2),
                      gap            = c(0.025, 0.025),
                      ext            = c(0.025, 0.025),
                      ratio          = 1.5,
                      base_size      = 11,
                      base_line_size = 0.5,
                      colour         = "black") +
  
  # Add theme
  theme(legend.position = "top")
  

Forest plot

my_results <- data.frame(
  subgroup   = c("men", "women", "35_49", "50_64", "65_79"),
  est        = c( 0.45,    0.58,    0.09,    0.35,     0.6),
  se         = c( 0.07,    0.06,    0.06,    0.05,    0.08)
)

forest <- forest_plot(my_results, printplot = FALSE)

The code now stored in forest$code and shown in the RStudio Viewer pane is:

library(ggplot2)

# Prepare data to be plotted using ckbplotr::forest_data()
datatoplot <- ckbplotr::forest_data(panels = my_results,
                                    panel.names = "1",
                                    col.estimate = "est",
                                    col.stderr = "se")

# Create the ggplot
ggplot(datatoplot, aes(y = row, x = estimate_transformed)) +

  # Put the different panels in side-by-side plots using facets
  facet_wrap(vars(panel), nrow = 1) +
  
  # Add a line at null effect
  annotate(geom      = "segment",
           y         = 0.7,
           yend      = Inf,
           x         = 1,
           xend      = 1,
           linewidth = 0.5,
           colour    = "black") +
  
  # Plot points at the transformed estimates
  geom_point(data   = ~ dplyr::filter(.x,
                                      estimate_transformed > 0.8,
                                      estimate_transformed < 2.2,
                                      !as_diamond),
             shape  = 15,
             size   = 3,
             colour = "black",
             fill   = "black",
             stroke = 0,
             na.rm  = TRUE) +
  
  # Plot the CIs
  geom_errorbar(aes(xmin = pmin(pmax(lci_transformed, 0.8), 2.2),
                    xmax = pmin(pmax(uci_transformed, 0.8), 2.2)),
                data = ~ dplyr::filter(.x, !is.na(estimate_transformed), !as_diamond),
                colour    = "black",
                width     = 0,
                linewidth = 0.5,
                na.rm     = TRUE) +
  
  # Add columns to right side of panels
  ## column auto_estcolumn
  ckbplotr::geom_text_move(aes(y = row,
                               x = 2.2,
                               label = `auto_estcolumn`),
                           move_x  = unit(0.9, "mm"),
                           hjust   = 0,
                           size    = 3.092846,
                           colour  = "black",
                           na.rm   = TRUE,
                           parse   = FALSE) +
  ckbplotr::geom_text_move(aes(y     = - 0,
                               x     = 2.2,
                               label = title),
                           move_x  = unit(0.9, "mm"),
                           hjust    = 0,
                           size     = 3.092846,
                           colour   = "black",
                           fontface = "bold",
                           lineheight = 1,
                           data = ~ dplyr::tibble(panel = sort(unique(.[["panel"]])),
                                                  title = "HR (95% CI)")) +
  
  # Add xlab below each axis
  geom_text(aes(y = Inf,
                x = 1.32665,,
                label = xlab),
            hjust    = 0.5,
            size     = 3.092846,
            colour   = "black",
            vjust    = 4.4,
            fontface = "bold",
            data = ~ dplyr::tibble(panel = sort(unique(.[["panel"]])),
                                   xlab = "HR (95% CI)")) +
  
  # Set coordinate system
  coord_cartesian(clip = "off",
                  xlim = c(0.8, 2.2)) +
  
  # Set the scale for the x axis (the estimates and CIs)
  scale_x_continuous(trans  = "log",
                     limits = c(0.8, 2.2),
                     breaks = c(0.5, 1, 1.5, 2, 2.5),
                     expand = c(0,0)) +
  
  # Set the scale for the y axis (the rows)
  scale_y_continuous(trans = "reverse",
                     breaks = attr(datatoplot, "rowlabels")$row,
                     labels = attr(datatoplot, "rowlabels")$row.label,
                     limits = c(max(attr(datatoplot, "rowlabels")$row) + 0.7, NA),
                     expand = c(0,0)) +
  
  # Control the overall look of the plot
  theme(text             = element_text(size = 11, colour = "black"),
        line             = element_line(linewidth = 0.5),
        panel.background = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        plot.title       = element_blank(),
        axis.line.x      = element_line(colour = "black", linewidth = 0.5, lineend = "round"),
        axis.title       = element_blank(),
        axis.ticks.x     = element_line(colour = "black"),
        axis.ticks.length.x = unit(2.75,  "pt"),
        axis.text.x      = element_text(colour = "black",,
                                        margin = margin(t = 4.4),
                                        vjust  = 1),
        axis.ticks.y     = element_blank(),
        axis.ticks.length.y = unit(0, "pt"),
        axis.line.y      = element_blank(),
        axis.text.y      = ggtext::element_markdown(hjust  = 0,
                                                    colour = "black",
                                                    margin = margin(r = 2.9, unit = "mm")),
        panel.border     = element_blank(),
        panel.spacing    = unit(24.5, "mm") + unit(5, "mm") + unit(2.9, "mm"),
        strip.background = element_blank(),
        strip.placement  = "outside",
        strip.text       = element_blank(),
        legend.position  = "none",
        plot.background  = element_blank(),
        plot.margin      = margin(8, 8, 8, 8, "mm") + unit(c(0, 24.5, 0, 0), "mm"))