Powered by AppSignal & Oban Pro

Guides for scales: guides

notebooks/guides.livemd

Guides for scales: guides

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

alias Giggly.Plot

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 guides(), 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.

Every scale is read back through a guide: an axis for a position scale, a legend or a colour bar for the others. Each scale's guide argument sets its guide; guides() sets them all at once, by aesthetic, each as a guide's name, such as "legend", or a call to a guide function. A guide set to "none" is left out, and legends that show the same values under the same title merge into one. Giggly reads each scale back as ggplot2 does by default: x and y with axes, a continuous colour or fill with a colour bar, and every other with a legend. It sets the guides of all but the axes with Giggly.Plot.guides/2 or a scale function's guide:, each by name, :colorbar, :legend or :none, or as the legend Giggly.Plot.guide_legend/1 builds, and merges legends that read alike, as ggplot2 does; it has no guide_colourbar(), nor guide_legend()'s title option. 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 guides ggplot2 chooses

p maps colour to a continuous column and size and shape to discrete ones (factor() makes a column discrete), so ggplot2 reads colour back with a colour bar and the others with legends.

# ggplot object

dat <- data.frame(x = 1:5, y = 1:5, p = 1:5, q = factor(1:5),
 r = factor(1:5))
p <-
  ggplot(dat, aes(x, y, colour = p, size = q, shape = r)) +
  geom_point()

# without guide specification
p

Giggly's table holds q and r as text, "1" to "5", a discrete column as R's factors are.

dat = %{
  "x" => Enum.to_list(1..5),
  "y" => Enum.to_list(1..5),
  "p" => Enum.to_list(1..5),
  "q" => ["1", "2", "3", "4", "5"],
  "r" => ["1", "2", "3", "4", "5"]
}

p =
  dat
  |> Plot.new(%{x: :x, y: :y, colour: :p, size: :q, shape: :r})
  |> Plot.geom_point()

render.(p)

Choosing each guide

# Show colorbar guide for colour.
# All these examples below have a same effect.

p + guides(colour = "colorbar", size = "legend", shape = "legend")
p + guides(colour = guide_colorbar(), size = guide_legend(),
  shape = guide_legend())
p +
 scale_colour_continuous(guide = "colorbar") +
 scale_size_discrete(guide = "legend") +
 scale_shape(guide = "legend")

Giggly draws the first and the third, where scale_colour_continuous() is Giggly.Plot.scale_color_continuous/2 and scale_shape() is Giggly.Plot.scale_shape_discrete/2; the second calls guide_colorbar(), ggplot2's other spelling of guide_colourbar().

p
|> Plot.guides(colour: :colorbar, size: :legend, shape: :legend)
|> render.()
p
|> Plot.scale_color_continuous(guide: :colorbar)
|> Plot.scale_size_discrete(guide: :legend)
|> Plot.scale_shape_discrete(guide: :legend)
|> render.()

Not in Giggly yet: guide_colourbar().

Removing guides

 # Remove some guides
 p + guides(colour = "none")
 p + guides(colour = "colorbar",size = "none")
p
|> Plot.guides(colour: :none)
|> render.()
p
|> Plot.guides(colour: :colorbar, size: :none)
|> render.()

Merged legends

Legends with the same title that show the same values merge into one, each key showing a colour, a size and a shape together.

# Guides are integrated where possible

p +
  guides(
    colour = guide_legend("title"),
    size = guide_legend("title"),
    shape = guide_legend("title")
 )
# same as
g <- guide_legend("title")
p + guides(colour = g, size = g, shape = g)

Not in Giggly yet: guide_legend()'s title option.

Legends below the plot

p + theme(legend.position = "bottom")
p
|> Plot.theme(legend_position: :bottom)
|> render.()

The order of the legends

# position of guides

# Set order for multiple guides
ggplot(mpg, aes(displ, cty)) +
  geom_point(aes(size = hwy, colour = cyl, shape = drv)) +
  guides(
   colour = guide_colourbar(order = 1),
   shape = guide_legend(order = 2),
   size = guide_legend(order = 3)
 )

Not in Giggly yet: guide_colourbar(), and the order option of guide_colourbar() and guide_legend(), which sets the order the guides are drawn in.