Home

Awesome

raincloudplots <img src="https://github.com/jorvlan/open-visualizations/blob/master/R/package_figures/rainclouds_highres.png" width="150" height="160" align="right"/>

<!---[![R-CMD-check](https://github.com/jorvlan/raincloudplots/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/jorvlan/raincloudplots/actions/workflows/R-CMD-check.yaml)--->

development version License: MIT CRAN status

If you use this package for your research, please cite it, thank you.

Paper

<pre> - Allen, M., Poggiali, D., Whitaker, K., Marshall, T. R., van Langen, J., & Kievit, R. A. Raincloud plots: a multi-platform tool for robust data visualization [version 2; peer review: 2 approved] <b>Wellcome Open Research</b> 2021, 4:63. <a href="https://doi.org/10.12688/wellcomeopenres.15191.2">https://doi.org/10.12688/wellcomeopenres.15191.2</a> </pre>

Background

It all started with the pre-print of raincloudplots in 2019 and accompanying GitHub repository RainCloudPlots. In the beginning of 2020, a tutorial called ‘open-visualizations’ was released and turned out to be a valuable addition to the previously published pre-print. This tutorial provides detailed and extensive R code to create robust and transparent repeated measures visualizations, by showing the slope change for each individual data point over time. To date (13-01-2021), this tutorial has been cited in 20 scientific papers. However, using this tutorial requires sufficient R programming knowledge and might therefore not be suitable for non-R experts. Therefore, we have created this dedicated raincloudplots package. This package is tailored towards easy visualization of grouped and repeated measures data. Moreover, it also provides individually linked repeated measures visualizations, which add detail and richness to a multitude of between/within-subject designs.

Package demonstration

Updates

<pre> - <b> January 2024</b> We have written a ggplot2-extension R-package <a href="https://github.com/njudd/ggrain">https://github.com/njudd/ggrain</a> which allows users to create Raincloud plots - following the 'Grammar of Graphics'. Please visit our newest repository at: <a href="https://github.com/njudd/ggrain">https://github.com/njudd/ggrain</a> - <b>February 2021 (version 0.2.0)</b> It is now possible to make raincloudplots with unequal 'between-group' comparisons (e.g., group1: 50 data-points, group2: 40 data-points) This is not possible for 'repeated-measures' between-timepoints (e.g., pre-post) connected by intra-individual lines `raincloudplots`. </pre>

Installation

if (!require(remotes)) {
    install.packages("remotes")
}
remotes::install_github('jorvlan/raincloudplots')

library(raincloudplots)

Raincloud 1 x 1

Step 1: Initialize the data-format

df_1x1 <- data_1x1(
  array_1 = iris$Sepal.Length[1:50],
  array_2 = iris$Sepal.Length[51:100],
  jit_distance = .09,
  jit_seed = 321)
> head(df_1x1)
  y_axis x_axis id       jit
1    5.1      1  1 1.0820609
2    4.9      1  2 1.0787114
3    4.7      1  3 0.9528797
4    4.6      1  4 0.9559133
5    5.0      1  5 0.9802922
6    5.4      1  6 0.9714124
> tail(df_1x1)
    y_axis x_axis id      jit
95     5.6      2 45 2.059387
96     5.7      2 46 2.004848
97     5.7      2 47 2.066980
98     6.2      2 48 2.074479
99     5.1      2 49 1.939248
100    5.7      2 50 1.999004

Step 2: Create a vertical or horizontal 1 x 1 raincloudplot

raincloud_1_h <- raincloud_1x1(
  data = df_1x1, 
  colors = (c('dodgerblue','darkorange')), 
  fills = (c('dodgerblue','darkorange')), 
  size = 1, 
  alpha = .6, 
  ort = 'h') +

scale_x_continuous(breaks=c(1,2), labels=c("Group1", "Group2"), limits=c(0, 3)) +
  xlab("Groups") + 
  ylab("Score") +
  theme_classic()

raincloud_1_h

Raincloud example

raincloud_1_v <- raincloud_1x1(
  data = df_1x1, 
  colors = (c('dodgerblue','darkorange')), 
  fills = (c('dodgerblue','darkorange')), 
  size = 1, 
  alpha = .6, 
  ort = 'v') +

scale_x_continuous(breaks=c(1,2), labels=c("Group1", "Group2"), limits=c(0, 3)) +
  xlab("Groups") + 
  ylab("Score") +
  theme_classic()

raincloud_1_v

Raincloud example

Raincloud 1 x 1 repeated measures

raincloud_2 <- raincloud_1x1_repmes(
  data = df_1x1,
  colors = (c('dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange')),
  line_color = 'gray',
  line_alpha = .3,
  size = 1,
  alpha = .6,
  align_clouds = FALSE) +
 
scale_x_continuous(breaks=c(1,2), labels=c("Pre", "Post"), limits=c(0, 3)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2

Raincloud example

raincloud_2_aligned <- raincloud_1x1_repmes(
  data = df_1x1,
  colors = (c('dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange')),
  line_color = 'gray',
  line_alpha = .3,
  size = 1,
  alpha = .6,
  align_clouds = TRUE) +
 
scale_x_continuous(breaks=c(1,2), labels=c("Pre", "Post"), limits=c(0, 3)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2_aligned

Raincloud example

Raincloud 2 x 2 repeated measures

Step 1: Initialize the data-format

df_2x2 <- data_2x2(
  array_1 = iris$Sepal.Length[1:50],
  array_2 = iris$Sepal.Length[51:100],
  array_3 = iris$Sepal.Length[101:150],
  array_4 = iris$Sepal.Length[81:130],
  labels = (c('congruent','incongruent')),
  jit_distance = .09,
  jit_seed = 321,
  spread_x_ticks = FALSE) 
> head(df_2x2)
  y_axis x_axis id     group       jit
1    5.1      1  1 congruent 1.0820609
2    4.9      1  2 congruent 1.0787114
3    4.7      1  3 congruent 0.9528797
4    4.6      1  4 congruent 0.9559133
5    5.0      1  5 congruent 0.9802922
6    5.4      1  6 congruent 0.9714124
> tail(df_2x2)
    y_axis x_axis id       group      jit
195    6.7   2.01 45 incongruent 2.056353
196    7.2   2.01 46 incongruent 1.975210
197    6.2   2.01 47 incongruent 2.011292
198    6.1   2.01 48 incongruent 2.013551
199    6.4   2.01 49 incongruent 1.961014
200    7.2   2.01 50 incongruent 2.086574
df_2x2_spread <- data_2x2(
  array_1 = iris$Sepal.Length[1:50],
  array_2 = iris$Sepal.Length[51:100],
  array_3 = iris$Sepal.Length[101:150],
  array_4 = iris$Sepal.Length[81:130],
  labels = (c('congruent','incongruent')),
  jit_distance = .09,
  jit_seed = 321,
  spread_x_ticks = TRUE) 
> head(df_2x2_spread)
  y_axis x_axis id     group       jit
1    5.1      1  1 congruent 1.0820609
2    4.9      1  2 congruent 1.0787114
3    4.7      1  3 congruent 0.9528797
4    4.6      1  4 congruent 0.9559133
5    5.0      1  5 congruent 0.9802922
6    5.4      1  6 congruent 0.9714124
> tail(df_2x2_spread)
    y_axis x_axis id       group      jit
195    6.7      4 45 incongruent 4.046353
196    7.2      4 46 incongruent 3.965210
197    6.2      4 47 incongruent 4.001292
198    6.1      4 48 incongruent 4.003551
199    6.4      4 49 incongruent 3.951014
200    7.2      4 50 incongruent 4.076574

Step 2: Create a raincloud plot with 4 x-ticks or with 2 x-ticks

raincloud_2x2 <- raincloud_2x2_repmes(
  data = df_2x2,
  colors = (c('dodgerblue', 'darkorange', 'dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange', 'dodgerblue', 'darkorange')),
  size = 1,
  alpha = .6,
  spread_x_ticks = FALSE) +

scale_x_continuous(breaks=c(1,2), labels=c("Pre", "Post"), limits=c(0, 3)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2x2

Raincloud example

raincloud_2x2_spread <- raincloud_2x2_repmes(
  data = df_2x2_spread,
  colors = (c('dodgerblue', 'darkorange', 'dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange', 'dodgerblue', 'darkorange')),
  line_color = 'gray',
  line_alpha = .3,
  size = 1,
  alpha = .6,
  spread_x_ticks = TRUE) +

scale_x_continuous(breaks=c(1,2,3,4), labels=c("Pre", "Post", "Pre", "Post"), limits=c(0, 5)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2x2_spread

Raincloud example

Raincloud 2 x 3 (repeated measures)

Step 1: Initialize the data-format

df_2x3 <- data_2x2(
  array_1 = iris$Sepal.Length[1:50],
  array_2 = iris$Sepal.Length[51:100],
  array_3 = iris$Sepal.Length[101:150],
  array_4 = iris$Sepal.Length[81:130],
  array_5 = iris$Sepal.Length[21:70],
  array_6 = iris$Sepal.Length[41:90],
  labels = (c('congruent','incongruent')),
  jit_distance = .05,
  jit_seed = 321) 
> head(df_2x3)
  y_axis x_axis id     group       jit
1    5.1      1  1 congruent 1.0455894
2    4.9      1  2 congruent 1.0437286
3    4.7      1  3 congruent 0.9738220
4    4.6      1  4 congruent 0.9755074
5    5.0      1  5 congruent 0.9890512
6    5.4      1  6 congruent 0.9841180
> tail(df_2x3)
    y_axis x_axis id       group      jit
295    5.4   3.01 45 incongruent 3.055610
296    6.0   3.01 46 incongruent 3.047695
297    6.7   3.01 47 incongruent 3.058535
298    6.3   3.01 48 incongruent 3.005049
299    5.6   3.01 49 incongruent 2.978512
300    5.5   3.01 50 incongruent 2.967493

Step 2: Create a vertical or horizontal 2 x 3 Raincloud

raincloud_2x3_vertical <- raincloud_2x3_repmes(
  data = df_2x3,
  colors = (c('dodgerblue', 'darkorange', 'dodgerblue',
              'darkorange', 'dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange', 'dodgerblue',
             'darkorange', 'dodgerblue', 'darkorange')),
  size = 1,
  alpha = .6,
  ort = 'v') +

scale_x_continuous(breaks=c(1,2,3), labels=c("T-1", "T-2", "T-3"), limits=c(0, 4)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2x3_vertical

Raincloud example

raincloud_2x3_horizontal <- raincloud_2x3_repmes(
  data = df_2x3,
  colors = (c('dodgerblue', 'darkorange', 'dodgerblue',
              'darkorange', 'dodgerblue', 'darkorange')),
  fills = (c('dodgerblue', 'darkorange', 'dodgerblue',
             'darkorange', 'dodgerblue', 'darkorange')),
  size = 1,
  alpha = .6,
  ort = 'h') +

scale_x_continuous(breaks=c(1,2,3), labels=c("T-1", "T-2", "T-3"), limits=c(0, 4)) +
  xlab("Time") + 
  ylab("Score") +
  theme_classic()

raincloud_2x3_horizontal

Raincloud example