Give a plot's colour and shape their own legend sections
Source:R/plot_legend.R
split_color_shape_legend.RdA ggplot mapping both colour and shape to discrete columns has two legends,
but plotly::ggplotly() merges them into one with an entry per combination,
named "(colour,shape)" under a "colour<br />shape" title. This draws them
as ggplot2 does instead: one legend in two titled sections, an entry per
colour level and one per shape level (in black, as ggplot2 draws shape keys).
Clicking an entry hides or shows every trace of its level, and
double-clicking one shows only its level (inst/src/legendSections.js).
Usage
split_color_shape_legend(
fig,
color.levels,
shape.levels,
color.title = NULL,
shape.title = NULL,
marker.size = 8
)Details
The point traces drawn for each combination are kept, out of the legend and
tagged with their levels (in meta). A trace drawn for a colour alone, such
as a yPlot's boxes ("(colour,1)", ggplot's placeholder shape for them),
becomes its level's colour entry; a level without one gets a data-less
legend-only trace, as does every shape level. Those are appended after the
existing traces, so no trace's index (a selection's curve number) moves.
Traces grouped under a colour level by name (the scatter plot's marginals)
are hidden and shown with it.
See also
apply_legend_styling(), whose title fonts style the section titles.
Examples
d <- transform(mtcars, am = factor(am), vs = factor(vs))
p <- ggplot2::ggplot(d, ggplot2::aes(wt, mpg, colour = am, shape = vs)) +
ggplot2::geom_point()
fig <- plotly::plotly_build(plotly::ggplotly(p))
fig <- split_color_shape_legend(fig, levels(d$am), levels(d$vs))