Powered by AppSignal & Oban Pro

Flipped coordinates: coord_flip

notebooks/coord_flip.livemd

Flipped coordinates: coord_flip

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

alias Giggly.Plot

diamonds = Giggly.Datasets.diamonds()

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

coord_flip() swaps the axes, so that what is mapped to x runs up the panel and what is mapped to y runs across it. It is superseded: swapping the x and y mappings, or setting a layer's orientation, draws the same plots, and coord_flip() remains for the geoms and stats that cannot be turned that way. Under it, the x scale and the xlim option act on the vertical axis, while the theme's settings for the x axis still act on the horizontal one, and facets keep their order. Giggly has no coord_flip() yet; its Giggly.Plot.geom_bar/3, Giggly.Plot.geom_histogram/3 and Giggly.Plot.geom_boxplot/3 turn on their side when y is mapped rather than x, and Giggly.Plot.geom_area/3 with orientation: :y, the swaps the page prefers. 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. It binds ggplot2's diamonds, Giggly.Datasets.diamonds/0, to diamonds, ggplot2's name for it.

Horizontal boxplots

# The preferred method of creating horizontal instead of vertical boxplots
ggplot(diamonds, aes(price, cut)) +
  geom_boxplot()

Mapping the cut to y stands the boxes along the vertical axis, the cuts in the order of their levels, from Fair to Ideal.

diamonds
|> Plot.new(%{x: :price, y: :cut})
|> Plot.geom_boxplot()
|> render.()

Flipping boxplots

# Using `coord_flip()` to make the same plot
ggplot(diamonds, aes(cut, price)) +
  geom_boxplot() +
  coord_flip()

Not in Giggly yet: coord_flip().

Reversing a horizontal histogram

# With swapped aesthetics, the y-scale controls the left axis
ggplot(diamonds, aes(y = carat)) +
  geom_histogram() +
  scale_y_reverse()

With y mapped, the bins run up the panel, and Giggly.Plot.scale_y_reverse/2 turns the left axis upside down.

Plot.new(diamonds, %{y: :carat})
|> Plot.geom_histogram()
|> Plot.scale_y_reverse()
|> render.()

Reversing a flipped histogram

# In `coord_flip()`, the x-scale controls the left axis
ggplot(diamonds, aes(carat)) +
  geom_histogram() +
  coord_flip() +
  scale_x_reverse()

Not in Giggly yet: coord_flip().

A horizontal area

# In line and area plots, swapped aesthetics require an explicit orientation
df <- data.frame(a = 1:5, b = (1:5) ^ 2)
ggplot(df, aes(b, a)) +
  geom_area(orientation = "y")

:math.pow/2 gives doubles, as R's ^ does.

df = %{"a" => Enum.to_list(1..5), "b" => Enum.map(1..5, fn value -> :math.pow(value, 2) end)}

df
|> Plot.new(%{x: :b, y: :a})
|> Plot.geom_area(orientation: :y)
|> render.()

Flipping an area

# The same plot with `coord_flip()`
ggplot(df, aes(a, b)) +
  geom_area() +
  coord_flip()

Not in Giggly yet: coord_flip().