Powered by AppSignal & Oban Pro

Sizes: scale_size

notebooks/scale_size.livemd

Sizes: scale_size

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

alias Giggly.Plot

mpg = Giggly.Datasets.mpg()

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_size(), which covers scale_radius(), scale_size_binned(), scale_size_area() and scale_size_binned_area() 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.

The size aesthetic is mostly for points and text. scale_size() maps a continuous column to their area, since area is what readers perceive, while scale_radius() maps it to their radius. scale_size_area() makes a value of 0 an area of 0. scale_size_binned() and scale_size_binned_area() are the binned counterparts of scale_size() and scale_size_area(), cutting the column into bins first. A line's width, once also set by size, is now the linewidth aesthetic. Giggly has Giggly.Plot.scale_size_continuous/2, Giggly.Plot.scale_size_area/2, Giggly.Plot.scale_radius/2 and Giggly.Plot.scale_size_discrete/2, but not ggplot2's short name, scale_size(), nor binned size scales (scale_size_binned(), scale_size_binned_area()), and by default maps a point's size to a column as ggplot2's default scale does, and draws the legend that reads it back, but not a text's size. 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.mpg/0, ggplot2's mpg: fuel economy for 234 cars of 38 popular models from 1999 to 2008, which the setup cell binds to mpg, ggplot2's name for it.

Size from a column

p <- ggplot(mpg, aes(displ, hwy, size = hwy)) +
   geom_point()
p
p + scale_size("Highway mpg")
p + scale_size(range = c(0, 10))

A scale's first argument titles its legend, and range sets the smallest and the largest sizes. scale_size() is Giggly.Plot.scale_size_continuous/2, its title name:.

p =
  mpg
  |> Plot.new(%{x: :displ, y: :hwy, size: :hwy})
  |> Plot.geom_point()

render.(p)
p
|> Plot.scale_size_continuous(name: "Highway mpg")
|> render.()
p
|> Plot.scale_size_continuous(range: {0, 10})
|> render.()

Zero as no size

# If you want zero value to have zero size, use scale_size_area:
p + scale_size_area()
p
|> Plot.scale_size_area()
|> render.()

Binned sizes

# Binning can sometimes make it easier to match the scaled data to the legend
p + scale_size_binned()

Not in Giggly yet: scale_size_binned() and the legend that reads it back.

Sizes from counts

# This is most useful when size is a count
ggplot(mpg, aes(class, cyl)) +
  geom_count() +
  scale_size_area()

geom_count() draws one point for each place that has rows, sized by how many it has.

mpg
|> Plot.new(%{x: :class, y: :cyl})
|> Plot.geom_count()
|> Plot.scale_size_area()
|> render.()

Size as radius

# If you want to map size to radius (usually bad idea), use scale_radius
p + scale_radius()
p
|> Plot.scale_radius()
|> render.()