I loved the blog post for raincloud plots. On a rainy day I’ve tried to tidy the code.

1. Libraries

library(tidyverse)
## ── Attaching packages ──────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## âś” ggplot2 2.2.1     âś” purrr   0.2.4
## âś” tibble  1.4.2     âś” dplyr   0.7.4
## âś” tidyr   0.8.0     âś” stringr 1.3.0
## âś” readr   1.1.1     âś” forcats 0.3.0
## ── Conflicts ─────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## âś– dplyr::filter() masks stats::filter()
## âś– dplyr::lag()    masks stats::lag()

2. source geom_flat_violin

source("https://gist.githubusercontent.com/benmarwick/2a1bb0133ff568cbe28d/raw/fb53bd97121f7f9ce947837ef1a4c65a73bffb3f/geom_flat_violin.R")

3. Read in data

my_data <- read_csv("https://data.bris.ac.uk/datasets/112g2vkxomjoo1l26vjmvnlexj/2016.08.14_AnxietyPaper_Data%20Sheet.csv")
## Parsed with column specification:
## cols(
##   .default = col_integer(),
##   AngerUH = col_double(),
##   DisgustUH = col_double(),
##   FearUH = col_double(),
##   HappyUH = col_double(),
##   SadUH = col_double(),
##   SurpriseUH = col_double()
## )
## See spec(...) for full column specifications.
#colnames(my_data)
#glimpse(my_data)

4. Tidy data to long format

my_datal <- my_data %>% 
  select(Participant, AngerUH, DisgustUH, FearUH, HappyUH) %>% 
  gather(c("AngerUH", "DisgustUH", "FearUH", "HappyUH"), 
         key = "EmotionCondition", value = "Sensitivity")

head(my_datal)
## # A tibble: 6 x 3
##   Participant EmotionCondition Sensitivity
##         <int> <chr>                  <dbl>
## 1           1 AngerUH                0.298
## 2           2 AngerUH                0.587
## 3           3 AngerUH                0.389
## 4           4 AngerUH                0.219
## 5           5 AngerUH                0.521
## 6           6 AngerUH                0.582

5. Make a new theme

raincloud_theme <- theme(
  text = element_text(size = 10),
  axis.title.x = element_text(size = 16),
  axis.title.y = element_text(size = 16),
  axis.text = element_text(size = 14),
  axis.text.x = element_text(angle = 45, vjust = 0.5),
  legend.title = element_text(size = 16),
  legend.text = element_text(size = 16),
  legend.position = "right",
  plot.title = element_text(lineheight = .8, face = "bold", size = 16),
  panel.border = element_blank(),
  panel.grid.minor = element_blank(),
  panel.grid.major = element_blank(),
  axis.line.x = element_line(colour = "black", size = 0.5, linetype = "solid"),
  axis.line.y = element_line(colour = "black", size = 0.5, linetype = "solid"))

6. Calculate summary stats

lb <- function(x) mean(x) - sd(x)
ub <- function(x) mean(x) + sd(x)

sumld <- my_datal %>% 
  select(-Participant) %>% 
  group_by(EmotionCondition) %>% 
  summarise_all(funs(mean, median, lower = lb, upper = ub))

sumld
## # A tibble: 4 x 5
##   EmotionCondition  mean median  lower upper
##   <chr>            <dbl>  <dbl>  <dbl> <dbl>
## 1 AngerUH          0.479  0.500 0.286  0.673
## 2 DisgustUH        0.469  0.480 0.260  0.679
## 3 FearUH           0.303  0.281 0.0915 0.514
## 4 HappyUH          0.536  0.540 0.392  0.679
groups(sumld) # just to show that after summarise there is no groups
## NULL

7. Ready to plot, first raincloud plot!

g <- 
  ggplot(data = my_datal, 
         aes(x = EmotionCondition, y = Sensitivity, fill = EmotionCondition)) +
  geom_flat_violin(position = position_nudge(x = .2, y = 0), alpha = .8) +
  geom_point(aes(y = Sensitivity, color = EmotionCondition), 
             position = position_jitter(width = .15), size = .5, alpha = 0.8) +
  geom_boxplot(width = .1, outlier.shape = NA, alpha = 0.5) +
  expand_limits(x = 5.25) +
  guides(fill = FALSE) +
  guides(color = FALSE) +
  scale_color_brewer(palette = "Spectral") +
  scale_fill_brewer(palette = "Spectral") +
  coord_flip() + # flip or not
  theme_bw() +
  raincloud_theme

g

8. Same plot - replacing the boxplot with a mean and confidence interval

g <- 
  ggplot(data = my_datal, 
         aes(x = EmotionCondition, y = Sensitivity, fill = EmotionCondition)) +
  geom_flat_violin(position = position_nudge(x = .2, y = 0), alpha = .8) +
  geom_point(aes(y = Sensitivity, color = EmotionCondition), 
             position = position_jitter(width = .15), size = .5, alpha = 0.8) +
  geom_point(data = sumld, aes(x = EmotionCondition, y = mean), 
             position = position_nudge(x = 0.3), size = 2.5) +
  geom_errorbar(data = sumld, aes(ymin = lower, ymax = upper, y = mean), 
                position = position_nudge(x = 0.3), width = 0) +
  expand_limits(x = 5.25) +
  guides(fill = FALSE) +
  guides(color = FALSE) +
  coord_flip() + # flip or not?
  scale_color_brewer(palette = "Spectral") +
  scale_fill_brewer(palette = "Spectral") +
  theme_bw() +
  raincloud_theme
## Warning: Ignoring unknown aesthetics: y
g

# note: this gives a Warning: Ignoring unknown aesthetics: y
# It is from the geom_errorbar, but when removed gives and error
# Error in FUN(X[[i]], ...) : object 'Sensitivity' not found

You can find the R markdown file here and the R script here. Thanks micahgallen for posting beautiful plots!

A side joke, I managed to write twice the wrong name instead of rain cloud plots, rainbow plots. Maybe because of the colours provided in the plots, maybe because I just don’t like rainy days like today.