Last active
March 26, 2021 19:07
-
-
Save jenniferthompson/d87e0043a2be6304907d1de9aa64ef83 to your computer and use it in GitHub Desktop.
Combine boxplots + ridgeplots using patchwork
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
## 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)) |
Note: If using a Github-only package is an issue, Winston Chang's multiplot
function would also work for this!
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
Result: