Powered by AppSignal & Oban Pro

Annotations: annotate

notebooks/annotate.livemd

Annotations: annotate

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

alias Giggly.Plot

mtcars = Giggly.Datasets.mtcars()

render = fn plot ->
  plot
  |> Giggly.to_svg()
  |> IO.iodata_to_binary()
  |> Kino.Image.new(:svg)
end

About this notebook

This notebook follows the examples on ggplot2's reference page for annotate(), 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.

annotate() adds a layer whose aesthetics are given as values rather than mapped from the data's columns: a label, a shaded rectangle or a segment placed by hand. Any geom can draw it but the reference lines, geom_abline(), geom_hline() and geom_vline(), which annotate on their own. Its positions take part in the scales, so the axes grow to show it, while every other aesthetic is set, so an annotation never appears in a legend. Giggly has Giggly.Plot.annotate/3, which draws with every geom Giggly has: points, bars, paths and lines, text and rectangles. A plot is described with Giggly.Plot and drawn with Giggly.to_svg/2, which returns an SVG document. The setup cell aliases Giggly.Plot, so the cells write Plot.new/2, and defines render, which draws a plot and shows it below the cell with Kino.Image. The data in these examples is Giggly.Datasets.mtcars/0, R's mtcars: 32 cars from the 1974 Motor Trend US magazine, which the setup cell binds to mtcars, R's name for it.

Text

p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
p + annotate("text", x = 4, y = 25, label = "Some text")
p + annotate("text", x = 2:5, y = 25, label = "Some text")

A vector of positions, as x = 2:5, places the same text at each; Giggly takes a list.

p =
  mtcars
  |> Plot.new(%{x: :wt, y: :mpg})
  |> Plot.geom_point()

p
|> Plot.annotate(:text, x: 4, y: 25, label: "Some text")
|> render.()
p
|> Plot.annotate(:text, x: [2, 3, 4, 5], y: 25, label: "Some text")
|> render.()

A shaded rectangle

p + annotate("rect", xmin = 3, xmax = 4.2, ymin = 12, ymax = 21,
  alpha = .2)
p
|> Plot.annotate(:rect, xmin: 3, xmax: 4.2, ymin: 12, ymax: 21, alpha: 0.2)
|> render.()

A segment

p + annotate("segment", x = 2.5, xend = 4, y = 15, yend = 25,
  colour = "blue")

Not in Giggly yet: geom_segment().

A point and its range

p + annotate("pointrange", x = 3.5, y = 20, ymin = 12, ymax = 28,
  colour = "red", size = 2.5, linewidth = 1.5)

Not in Giggly yet: geom_pointrange().

A label at each position

p + annotate("text", x = 2:3, y = 20:21, label = c("my label", "label 2"))

Vectors of positions and labels give one annotation per value, taken in step.

p
|> Plot.annotate(:text, x: [2, 3], y: [20, 21], label: ["my label", "label 2"])
|> render.()

Mathematical labels

p + annotate("text", x = 4, y = 25, label = "italic(R) ^ 2 == 0.75",
  parse = TRUE)
p + annotate("text", x = 4, y = 25,
  label = "paste(italic(R) ^ 2, \" = .75\")", parse = TRUE)

parse = TRUE reads each label as one of R's plotmath expressions, so italic(R) ^ 2 is drawn as an italic R, squared.

Not in Giggly yet: geom_text()'s parse option and R's plotmath expressions.