Skip to content

Instantly share code, notes, and snippets.

@jenniferthompson
Last active March 26, 2021 19:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jenniferthompson/d87e0043a2be6304907d1de9aa64ef83 to your computer and use it in GitHub Desktop.
Save jenniferthompson/d87e0043a2be6304907d1de9aa64ef83 to your computer and use it in GitHub Desktop.
Combine boxplots + ridgeplots using patchwork
################################################################################
## Example code for generating side-by-side boxplots + raw data and ridgeplots
## NOTE: Uses Thomas Lin Pedersen's patchwork package, not yet on CRAN @ writing
################################################################################
## devtools::install_github("thomasp85/patchwork")
library(patchwork)
library(ggridges)
library(tidyverse)
## for data generation & management; could do this with base, of course, but I
## know my target audience is OK with tidyverse functions :)
## Generate example data, ~100 obs each at 5 time points; median inc across time
df <- data.frame(
time = rep(1:5, each = 100),
x = purrr::map(1:5, rnorm, n = 100) %>% purrr::flatten_dbl()
)
## Format data for plotting: we want to show entire distribution at the top in
## one color, plus each time point separately; concatenate original data and add
## an overall/not indicator
df_plot <- bind_rows(
df %>% mutate(time = 0, overall = TRUE),
df %>% mutate(overall = FALSE)
) %>%
## Make a factor version of time, reversing the order so that 0, 1, 2... goes
## top to bottom
mutate(
time_f = forcats::fct_rev(
factor(time, levels = 0:5, labels = c("Overall", 1:5))
)
)
## -- Create boxplots ----------------------------------------------------------
bp <- ggplot(data = df_plot, aes(x = time_f, y = x, group = time_f)) +
## Include raw data behind boxplots
geom_point(aes(colour = overall),
alpha = 0.2, position = position_jitter(width = 0.1)) +
## Add boxplots, with no fill or outliers so raw data is visible
## Line size is thicker for overall than for individual times
geom_boxplot(aes(size = overall), fill = NA, outlier.shape = NA) +
scale_size_manual(values = c(0.5, 1.0), guide = FALSE) +
## Flip it so time is vertical
coord_flip() +
## Visual tweaks to go with our usual look
scale_colour_manual(values = c("#B40F20", "#003D74"), guide = FALSE) +
theme_bw() +
labs(y = "Example Boxplot", x = NULL) +
theme(
axis.ticks.y = element_blank(), ## I don't think ticks are helpful here
axis.text.y = element_text(face = "bold", size = 14)
)
## -- Create ridgeplots --------------------------------------------------------
## Using Claus Wilke's ggridges package
rp <- ggplot(data = df_plot, aes(y = time_f, x = x)) +
ggridges::geom_density_ridges(aes(fill = overall), alpha = 0.8) +
## Visual tweaks
scale_fill_manual(values = c("#B40F20", "#003D74"), guide = FALSE) +
theme_bw() +
## Clean up that Y axis
theme(
axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank()
) +
labs(x = "Example ridgeplot")
## -- Combine boxplots + ridgeplots to display together ------------------------
bp + rp + plot_layout(ncol = 2, widths = c(2, 1))
@jenniferthompson
Copy link
Author

jenniferthompson commented Mar 12, 2018

Result:

boxridge

@jenniferthompson
Copy link
Author

Note: If using a Github-only package is an issue, Winston Chang's multiplot function would also work for this!

@d4tagirl
Copy link

Thank you! :D I’m more than ok with your using of the tidyverse ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment