Powered by AppSignal & Oban Pro

Line types: scale_linetype

notebooks/scale_linetype.livemd

Line types: scale_linetype

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

alias Giggly.Plot

economics_long = Giggly.Datasets.economics_long()

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 scale_linetype(), which covers scale_linetype_binned(), scale_linetype_continuous() and scale_linetype_discrete() too, 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.

scale_linetype() maps a discrete column to line patterns, solid, dashed, dotted and others, from a default set supplied by Richard Pearson of the University of Manchester. A continuous column can be mapped to line types only through scale_linetype_binned(), which cuts it into bins first, and since patterns have no order even that is not advised. A line type can be named by number, by name or by a string of hex digits, and a missing one is drawn blank. Giggly has Giggly.Plot.scale_linetype_discrete/2 and Giggly.Plot.scale_linetype_manual/2, a line type named by number, by name as an atom or as a dash pattern, a tuple of lengths, but not ggplot2's short name, scale_linetype(), nor binned or identity line type scales (scale_linetype_binned(), scale_linetype_identity()), and by default maps linetype to a discrete column as ggplot2's default scale does, and draws the legend that reads it back. 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 is Giggly.Datasets.economics_long/0, ggplot2's economics_long: five US economic time series, a row for each month and series, which the setup cell binds to economics_long, ggplot2's name for it.

A line type for each series

base <- ggplot(economics_long, aes(date, value01))
base + geom_line(aes(group = variable))
base + geom_line(aes(linetype = variable))

value01 is each series rescaled to run from 0 to 1, so all five share an axis.

base = Plot.new(economics_long, %{x: :date, y: :value01})

base
|> Plot.geom_line(%{group: :variable})
|> render.()
base
|> Plot.geom_line(%{linetype: :variable})
|> render.()

Line types by hand

# See scale_manual for more flexibility

The comment points to ggplot2's scale_manual page, where scale_linetype_manual() gives each value a pattern chosen by hand. Giggly's is Giggly.Plot.scale_linetype_manual/2.

Common line types

A table of common patterns, as a factor whose levels keep the order they are written in, each drawn as a thick horizontal line in a panel of its own. scale_linetype_identity() draws each line in the pattern its value names, and theme_void(20) draws no axes, grid or background, at a base font size of 20.

# Common line types ----------------------------
df_lines <- data.frame(
  linetype = factor(
    1:4,
    labels = c("solid", "longdash", "dashed", "dotted")
  )
)
ggplot(df_lines) +
  geom_hline(aes(linetype = linetype, yintercept = 0), linewidth = 2) +
  scale_linetype_identity() +
  facet_grid(linetype ~ .) +
  theme_void(20)

Not in Giggly yet: horizontal lines (geom_hline()) and scale_linetype_identity().