Powered by AppSignal & Oban Pro

Manual transformations: stat_manual

notebooks/stat_manual.livemd

Manual transformations: stat_manual

Mix.install([
  {:giggly, path: Path.join(__DIR__, "..")},
  {:kino, "~> 0.19"}
  ])

About this notebook

This notebook follows the examples on ggplot2's reference page for stat_manual(), in the order the page gives them. Each example shows ggplot2's code first and then Giggly's. An example Giggly cannot draw yet keeps its ggplot2 code and names what it is waiting for, so the page is also a list of what remains.

stat_manual() makes a stat of any function: the function is given the rows of each group as a data frame and returns the rows to draw, and args passes it further arguments. A column that is constant within a group is kept even if the function drops it. Its default function, identity(), returns the rows unchanged. Giggly has none of it yet.

The rows as they are

# A standard scatterplot
p <- ggplot(mtcars, aes(disp, mpg, colour = factor(cyl))) +
  geom_point()

# The default just displays points as-is
p + stat_manual()

stat_manual() draws points by default, so this draws the points of p a second time, over the first.

Not in Giggly yet: stat_manual().

A hull from a function

# Using a custom function
make_hull <- function(data) {
  hull <- chull(x = data$x, y = data$y)
  data.frame(x = data$x[hull], y = data$y[hull])
}

p + stat_manual(
  geom = "polygon",
  fun  = make_hull,
  fill = NA
)

R's chull() finds the points on a group's convex hull, the outline that encloses them all, and the polygon joins them.

Not in Giggly yet: stat_manual() and its fun option, polygons, and geom_polygon(), besides what p waits for.

A hull from a quoted expression

# Using the `with` function with quoting
p + stat_manual(
  fun  = with,
  args = list(expr = quote({
    hull <- chull(x, y)
    list(x = x[hull], y = y[hull])
  })),
  geom = "polygon", fill = NA
)

with() evaluates the quoted expression among each group's columns.

Not in Giggly yet: stat_manual() and its fun and args options and geom_polygon(), besides what p waits for.

Segments to the centre

# Using the `transform` function with quoting
p + stat_manual(
  geom = "segment",
  fun  = transform,
  args = list(
    xend = quote(mean(x)),
    yend = quote(mean(y))
  )
)

transform() gives each row an xend and a yend at its group's mean, so a segment runs from each point to the centre of its group.

Not in Giggly yet: stat_manual() and its fun and args options, and segments, geom_segment(), besides what p waits for.

Centroids with dplyr

The rest of the examples run only where the dplyr package is installed. vars() quotes the expressions its verbs evaluate.

# Using dplyr verbs with `vars()`
if (requireNamespace("dplyr", quietly = TRUE)) {

  # Get centroids with `summarise()`
  p + stat_manual(
    size = 10, shape = 21,
    fun  = dplyr::summarise,
    args = vars(x = mean(x), y = mean(y))
  )

dplyr::summarise() reduces each group to one row at its mean, drawn as a large hollow circle.

Not in Giggly yet: stat_manual() and its fun and args options, and the dplyr package's verbs, besides what p waits for.

Segments with dplyr

  # Connect to centroid with `mutate`
  p + stat_manual(
    geom = "segment",
    fun  = dplyr::mutate,
    args = vars(xend = mean(x), yend = mean(y))
  )

Not in Giggly yet: stat_manual() and its fun and args options, the dplyr package's verbs, and geom_segment(), besides what p waits for.

A hull with dplyr

  # Computing hull with `reframe()`
  p + stat_manual(
    geom = "polygon", fill = NA,
    fun  = dplyr::reframe,
    args = vars(hull = chull(x, y), x = x[hull], y = y[hull])
  )
}

Not in Giggly yet: stat_manual() and its fun and args options, the dplyr package's verbs, and geom_polygon(), besides what p waits for.