This page shows every way you can change a forestmap plot, with an
example of each. All the examples use the forestmap_example
data that comes with the package. Most use two study properties to keep
the plots small, but everything works the same with more.
Headings and order
Headings
Name each property to set its heading. Without a name, the column name is used:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Who took part" = "population", "design")
)
Which properties, in which order
The heatmap shows the properties you list, in the order you list them:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Country" = "country", "Population" = "population")
)
Order and names of the rows
Rows follow the order of the factor’s levels. Change the order with
factor(..., levels = ...), and rename levels with
labels = ...:
dat <- forestmap_example
dat$population <- factor(
dat$population,
levels = c("Clinical", "Children", "Adults"),
labels = c("Clinical samples", "Children (< 18)", "Adults (18+)")
)
plot_forestmap(
dat, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design")
)
Axis titles
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
y_label = "Hedges' g (95% CI)",
x_label = "Studies, sorted by effect size"
)
Effect size scale
Ratios: null_value
Colours depend on whether each confidence interval excludes the value
meaning “no effect”. That’s 0 for differences (and log ratios) and 1 for
ratios such as odds ratios. Odds-ratio intervals aren’t symmetric, so
give the bounds with lb and ub rather than a
variance. Here the example effects are converted to odds ratios:
odds <- forestmap_example
to_log_or <- pi / sqrt(3)
odds$or <- exp(odds$smd * to_log_or)
odds$or_lower <- exp((odds$smd - 1.96 * sqrt(odds$vi)) * to_log_or)
odds$or_upper <- exp((odds$smd + 1.96 * sqrt(odds$vi)) * to_log_or)
plot_forestmap(
odds, "or", "or_lower", "or_upper",
moderators = c("Population" = "population", "Study design" = "design"),
null_value = 1,
y_label = "Odds ratio (95% CI)"
)
Ratios are often easier to read on the log scale: plot
log(or) with its variance (vi) and the default
null_value = 0.
Effects too small to matter: rope
rope shades a band of effects you consider too small to
matter (a “region of practical equivalence”). Give two numbers, or one
number for a band symmetric around null_value:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
rope = c(-0.1, 0.1)
)
Axis range: y_limits
By default the y-axis is symmetric around null_value and
wide enough to show every confidence interval (for ratios, it starts at
0). Set your own range with y_limits; parts of intervals
outside it are cut off:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
y_limits = c(-1, 1.2)
)
Colours
Built-in palettes
Choose a palette by name. The options are "default"
(shown in the examples above), "okabe_ito",
"viridis" and "greyscale".
"okabe_ito" uses blue and vermillion from the Okabe–Ito
palette, designed to stay distinguishable for people with common types
of colour blindness:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
palette = "okabe_ito"
)
"viridis":
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
palette = "viridis"
)
"greyscale", for black-and-white printing:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
palette = "greyscale"
)
Your own colours
Give three colours: for positive effects, negative effects, and effects whose interval includes the null value. Any colour name or hex code works:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
palette = c(positive = "#1b7837", negative = "#762a83", null = "grey75")
)
Font and text size
Font
font takes the name of any font installed on your
computer. The default, "Roboto Condensed", comes with
forestmap, so it works everywhere; so do the generic names
"sans", "serif" and "mono":
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
font = "serif"
)
To see which fonts you have, run
systemfonts::system_fonts()$family. You can also use a font
file that isn’t installed, by giving its path:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
font = "fonts/MyFont-Regular.ttf"
)Text size
text_size sets the size of all text, in points (default
9):
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
text_size = 12
)
Panel heights
By default, the heatmap gets more of the plot’s height the more rows
it has. forest_height sets the forest plot’s share of the
height yourself, between 0 and 1. Here the forest plot and heatmap get
half each:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design"),
forest_height = 0.5
)
Many study properties
With many properties or levels the heatmap gets tall. Two options help.
Compact layout
layout = "compact" puts each property’s name beside its
rows instead of on a row of its own:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c(
"Population" = "population",
"Outcome measure" = "outcome",
"Study design" = "design",
"Country" = "country"
),
layout = "compact"
)
Fewer rows: max_levels
max_levels sets the most rows any property can have. The
most common levels are kept, and the rest are merged into one “Other”
row. With max_levels = 3, the five countries become USA,
Australia and Other:
plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c(
"Population" = "population",
"Outcome measure" = "outcome",
"Study design" = "design",
"Country" = "country"
),
layout = "compact",
max_levels = 3
)
If several levels tie for the last place, all of them are kept and you get a warning saying so.
Going further with ggplot2 and patchwork
plot_forestmap() returns a patchwork of two ggplot2
plots: p[[1]] is the forest plot and p[[2]]
the heatmap. You can add to either one.
Title and caption
p <- plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design")
)
p + patchwork::plot_annotation(
title = "Effects of the intervention",
subtitle = "60 studies, sorted by effect size",
caption = "Simulated data"
)
Show the pooled effect
Add a line to the forest plot, for example at the pooled effect from your meta-analysis. Here it’s a simple inverse-variance (fixed-effect) average:
pooled <- weighted.mean(forestmap_example$smd, w = 1 / forestmap_example$vi)
p <- plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design")
)
p[[1]] <- p[[1]] +
ggplot2::geom_hline(yintercept = pooled, colour = "black", linewidth = 0.4) +
ggplot2::annotate(
"text", x = 1, y = pooled, label = "Pooled effect",
hjust = 0, vjust = -0.6, size = 3, family = "Roboto Condensed"
)
p
Text added with annotate() doesn’t pick up the plot’s
font automatically, so set family to the font the plot uses
("Roboto Condensed" unless you chose another).
Axis breaks
Change where the y-axis labels go with
scale_y_continuous(). Use round numbers; seq()
can create tiny rounding errors that show up as odd labels:
p <- plot_forestmap(
forestmap_example, "smd", vi = "vi",
moderators = c("Population" = "population", "Study design" = "design")
)
p[[1]] <- p[[1]] + ggplot2::scale_y_continuous(breaks = c(-1, -0.5, 0, 0.5, 1))
p
Saving
plot_forestmap() doesn’t save anything; use
ggplot2::ggsave() and choose the size there. The plot looks
best at around 7 × 5 inches with four properties; add height as you add
rows.
ggplot2::ggsave("forestmap.png", p, width = 7, height = 5.25, dpi = 300)
ggplot2::ggsave("forestmap.svg", p, width = 7, height = 5.25)
ggplot2::ggsave("forestmap.pdf", p, width = 7, height = 5.25, device = cairo_pdf)For PDFs, use device = cairo_pdf. PDFs (and RStudio’s
Plots pane) only see fonts installed on your computer, so install Roboto
Condensed (from
system.file("fonts", package = "forestmap")) or choose an
installed font. In RStudio you can instead set Tools > Global
Options > General > Graphics > Backend to
AGG.