Skip to contents

Draws an interactive raincloud plot using plotly. With option to show or hide each of half-violin density plots, boxplots, and scatter plots of the raw values.

Usage

plot_raincloud_ly(
  data,
  x,
  y,
  colors = NULL,
  show_density = TRUE,
  show_scatter = TRUE,
  show_box = TRUE,
  show_buttons = TRUE,
  button_options = list(),
  show_legend = FALSE,
  density_width = 0.38,
  density_opacity = 0.45,
  scatter_layout = c("jitter", "stacked"),
  scatter_size = 6,
  scatter_opacity = 0.65,
  scatter_box_gap = box_width/2 + 0.025,
  scatter_width = 0.2,
  scatter_binwidth = NULL,
  box_width = 0.16,
  boxpoints = FALSE,
  boxmean = TRUE,
  ...
)

Arguments

data

A data frame.

x, y

Single strings naming columns of `data`. One must be numeric and the other categorical.

colors

Optional character vector of colours. A named vector is matched to group names; an unnamed vector is assigned in group order. If `NULL`, colours come from [grDevices::hcl.colors()].

show_density, show_scatter, show_box

Logical; whether each element is initially visible.

show_buttons

Logical; add buttons that toggle each element.

button_options

Named list of plotly `updatemenus` attributes applied to every button, such as `x`, `y`, `xanchor`, `yanchor`, `bgcolor` or `font`; see [plotly::layout()]. The buttons sit below the bottom left of the plot by default and are spread 80 pixels apart, so `x` and `y` place the first button. A `pad` is merged with the defaults, and its `l` is added to that spacing. If `y` is given, the default top padding and the extra bottom margin are dropped; adjust the margin with `plotly::layout(margin = ...)`. `type`, `buttons`, `active` and `showactive` cannot be set.

show_legend

Logical; show one legend entry per group.

density_width

Maximum width of the half-violin, in units of the distance between groups.

density_opacity

Fill opacity of the density, between 0 and 1.

scatter_layout

Point placement: `"jitter"` (random) or `"stacked"` (stacked within bins).

scatter_size

Marker size.

scatter_opacity

Marker opacity, between 0 and 1.

scatter_box_gap

Distance from the group position to the nearest points, in units of the distance between groups. The default, `box_width / 2 + 0.025`, starts points just outside the box edge.

scatter_width

Width of the scatter, measured from `scatter_box_gap`, in units of the distance between groups. For `"jitter"` it is the width of the band of random positions; for `"stacked"` the tallest stack spans exactly this width, so dots are spaced further apart or closer together as it changes. Use `0` to put all points in a single column.

scatter_binwidth

Bin width along the numeric axis when `scatter_layout = "stacked"`. If `NULL`, one thirtieth of the data range.

box_width

Width of the boxplot.

boxpoints

Passed to [plotly::add_boxplot()]; `FALSE`, `"outliers"` or `"suspectedoutliers"`.

boxmean

Passed to [plotly::add_boxplot()]; `TRUE`, `FALSE` or `"sd"`.

...

Additional arguments passed to [plotly::plot_ly()].

Value

A plotly object.

Details

Exactly one of `x` or `y` must be numeric and the other categorical: * categorical `x` and numeric `y` give a vertical plot; * numeric `x` and categorical `y` give a horizontal plot.

Rows with missing values in either column are dropped. Group order follows the factor levels (unused levels are dropped), otherwise the order of first appearance. Each group uses one colour across all three elements.

With `scatter_layout = "stacked"`, values are binned along the numeric axis and stacked along the categorical axis, which approximates stacked-dot displays without overlapping points. With `"jitter"` the positions are random, so use [set.seed()] for reproducible plots. With `scatter_width = 0`, both layouts put all points in a single column.

Hovering a point shows its value and hovering inside a box shows its statistics. Plotly shows the nearest point within `hoverdistance` pixels before any box, so the plot sets `hoverdistance = 3`, which is about the marker radius. To change the hover distance, use `plotly::layout(hoverdistance = ...)`. For every layout, points start `scatter_box_gap` away from the group position.

Elements switched off with `show_density`, `show_scatter` or `show_box` are still added to the plot, but start hidden, so that the buttons can reveal them.

Examples

set.seed(1)
plot_raincloud_ly(iris,
                  x = "Species",
                  y = "Sepal.Length",
                  scatter_layout = "jitter",
                  show_buttons = FALSE)
# Buttons along the top left of the plot plot_raincloud_ly(iris, x = "Species", y = "Sepal.Length", button_options = list(y = 1.15, yanchor = "top")) |> plotly::layout(margin = list(t = 80))
plot_raincloud_ly(iris, x = "Sepal.Length", y = "Species", colors = c("#11A7F2", "#E00087", "#00bdaa"), scatter_layout = "stacked", show_box = FALSE, show_legend = TRUE) |> plotly::layout(yaxis = list(showticklabels = FALSE), legend = list(x = 1, y = -0.2, xanchor = "right", orientation = "h"))