Skip to contents

Draws the distribution of the plotted X values in a strip above a single-panel plotly figure, and of the Y values in a strip to its right, as a density curve, a histogram, a rug, or any combination of them. One trace is drawn per group, in that group's colour, and the rug gives each group its own lane so groups do not overplot.

Usage

add_marginal_plots(
  fig,
  x,
  y,
  groups = NULL,
  colors = "#000000",
  top = character(0),
  right = character(0),
  top.size = 0.15,
  right.size = 0.15,
  opacity = 0.5,
  bins = 30,
  binwidth = NULL,
  density.adjust = 1,
  rug.size = 0.3,
  rug.length = 0.8,
  rug.width = 1,
  gap = 0.02,
  show.axes = FALSE
)

Arguments

fig

A single-panel plotly figure.

x, y

Numeric vectors of the plotted X and Y values, one per point. Pass the values as drawn (after any data adjustment), not the raw data. Non-finite values are dropped.

groups

A vector or factor of the same length giving each point's group, or NULL for a single ungrouped distribution. Factor levels set the order of the rug lanes.

colors

Colours for the groups: a vector named by group, or an unnamed vector recycled over the groups in level order. Without groups, the first colour is used.

top, right

Character vectors of the marginals to draw above the plot (for x) and to its right (for y), any of "density", "histogram" and "rug". An empty vector draws nothing on that side.

top.size, right.size

Fraction of the plot's height (top.size) or width (right.size) given to that side's marginals, from 0.02 to 0.8.

opacity

Opacity of the density and histogram fills and of the rug lines, 0 to 1.

bins

Number of histogram bins, spanning the range of all groups' values.

binwidth

Histogram bin width. When given, it overrides bins, and the bins are aligned to multiples of it.

density.adjust

Multiplier on the density bandwidth, as adjust in stats::density(). Larger values smooth more.

rug.size

Share of a side's strip given to the rug when the side also has a density or histogram, 0.1 to 0.9. A rug on its own fills the side.

rug.length

Length of each rug tick as a fraction of its group's lane, 0 to 1.

rug.width

Line width of the rug ticks, in pixels.

gap

Paper-space gap between the main panel and the marginals.

show.axes

Logical. Whether each density or histogram strip shows its density or count axis, with a line, a few ticks, and their labels. The strips' value axes, which repeat the plot's own, and the rug strips stay bare. Default FALSE.

Value

The built plotly figure with the marginals added, or fig unchanged when top and right are both empty.

Details

The main panel is shrunk to make room, and each strip's value axis matches the main axis, so zooming or panning the plot moves its marginals with it. Paper-anchored shapes (such as the panel border ggplotly draws) and axis-title annotations from axis_titles_as_annotations() are moved into the shrunk panel.

Call this last, once everything else has been drawn: helpers that work per panel (fit lines, reference lines, axis styling) read the strips' extra axes as facet panels. It is not meant for a faceted figure.

A density and a histogram on the same side share one strip, the histogram drawn first and scaled to a density (count / (n * bin width)) so both share a scale; a histogram on its own shows counts. A rug sits in a strip of its own, between the main panel and any density or histogram. Densities, like ggplot2's, span each group's range of values. Every marginal is a line trace, so box and lasso selection pick only the plot's points, and each takes its group's legendgroup, so hiding a group from the legend hides its marginals too.

Author

Jared Andrews

Examples

library(plotly)
df <- example_iris
fig <- plot_ly(df,
    x = ~Sepal.Length, y = ~Sepal.Width, color = ~Species,
    type = "scatter", mode = "markers"
)
add_marginal_plots(fig,
    x = df$Sepal.Length, y = df$Sepal.Width, groups = df$Species,
    colors = c("#E69F00", "#56B4E9", "#009E73"),
    top = c("density", "rug"), right = "histogram"
)