Colour, fill and alpha: aes_colour_fill_alpha
Mix.install([
{:giggly, path: Path.join(__DIR__, "..")},
{:kino, "~> 0.19"}
])
alias Giggly.Plot
economics = Giggly.Datasets.economics()
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
aes_colour_fill_alpha, 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.
colour and fill give a geom its colours, and alpha its opacity. colour draws lines and
outlines: points, lines, and the borders of rectangles and polygons. fill colours the inside of an
area: rectangles, polygons, and the point shapes 21 to 25. A colour is one of R's named colours,
such as "red", an RGB specification, "#RRGGBB", which may add an alpha as "#RRGGBBAA", or
NA, for no colour at all; alpha runs from 0, transparent, to 1, opaque. Giggly has all three,
mapped to a column or set to a value, a set colour written as CSS writes one: a name, a hex colour,
or :none for NA. Where R and CSS give a name different colours, as "green", it is CSS's, and a
name CSS lacks, as R's "grey50", is written as its hex. 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 Giggly.Datasets.economics/0, ggplot2's economics, and
Giggly.Datasets.mtcars/0, R's mtcars, to economics and mtcars, the names ggplot2 and R give
them.
The default bars
# Bar chart example
p <- ggplot(mtcars, aes(factor(cyl)))
# Default plotting
p + geom_bar()
factor(cyl) makes the number of cylinders discrete, so the axis has a place for each of 4, 6
and 8. Giggly writes it {:factor, [:cyl]}, and titles the axis factor(cyl), as ggplot2 does.
p = Plot.new(mtcars, %{x: {:factor, [:cyl]}})
p
|> Plot.geom_bar()
|> render.()
Fill and outline colour
# To change the interior colouring use fill aesthetic
p + geom_bar(fill = "red")
# Compare with the colour aesthetic which changes just the bar outline
p + geom_bar(colour = "red")
# Combining both, you can see the changes more clearly
p + geom_bar(fill = "white", colour = "red")
fill: and colour: set every bar's inside and border; "red" and "white" are the same
colours in CSS as in R.
p
|> Plot.geom_bar(fill: "red")
|> render.()
p
|> Plot.geom_bar(colour: "red")
|> render.()
p
|> Plot.geom_bar(fill: "white", colour: "red")
|> render.()
RGB colours, and none
# Both colour and fill can take an rgb specification.
p + geom_bar(fill = "#00abff")
# Use NA for a completely transparent colour.
p + geom_bar(fill = NA, colour = "#00abff")
A hex colour is written as R writes it, and :none is R's NA, no colour at all.
p
|> Plot.geom_bar(fill: "#00abff")
|> render.()
p
|> Plot.geom_bar(fill: :none, colour: "#00abff")
|> render.()
Mapping fill to a discrete column
# Colouring scales differ depending on whether a discrete or
# continuous variable is being mapped. For example, when mapping
# fill to a factor variable, a discrete colour scale is used.
ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) + geom_bar()
factor(vs) reads the engine shape, 0 or 1, as two levels, so the fill takes a discrete scale and
each bar a stack of two.
mtcars
|> Plot.new(%{x: {:factor, [:cyl]}, fill: {:factor, [:vs]}})
|> Plot.geom_bar()
|> render.()
Mapping fill to a continuous column
# When mapping fill to continuous variable a continuous colour
# scale is used.
ggplot(faithfuld, aes(waiting, eruptions)) +
geom_raster(aes(fill = density))
Not in Giggly yet: the faithfuld dataset and geom_raster().
Geoms with colour only
# Some geoms only use the colour aesthetic but not the fill
# aesthetic (e.g. geom_point() or geom_line()).
p <- ggplot(economics, aes(x = date, y = unemploy))
p + geom_line()
p + geom_line(colour = "green")
p + geom_point()
p + geom_point(colour = "red")
A line and points take colour:, and have no fill to set. A colour is named as CSS names it, and
"green" is CSS's, #008000, darker than R's, #00FF00, so this line is darker than ggplot2's;
"red" is #FF0000 in both.
p = Plot.new(economics, %{x: :date, y: :unemploy})
p
|> Plot.geom_line()
|> render.()
p
|> Plot.geom_line(colour: "green")
|> render.()
p
|> Plot.geom_point()
|> render.()
p
|> Plot.geom_point(colour: "red")
|> render.()
Transparency for overplotting
# For large datasets with overplotting the alpha
# aesthetic will make the points more transparent.
set.seed(1)
df <- data.frame(x = rnorm(5000), y = rnorm(5000))
p <- ggplot(df, aes(x,y))
p + geom_point()
p + geom_point(alpha = 0.5)
p + geom_point(alpha = 1/10)
R's rnorm() draws the points at random from a normal distribution, the same ones every time
after set.seed(1).
Giggly draws all three now, but this notebook leaves them undrawn: it would have to write out the
10,000 numbers rnorm() draws here.
Shading with alpha
# Alpha can also be used to add shading.
p <- ggplot(economics, aes(x = date, y = unemploy)) + geom_line()
p
yrng <- range(economics$unemploy)
p <- p +
geom_rect(
aes(NULL, NULL, xmin = start, xmax = end, fill = party),
ymin = yrng[1], ymax = yrng[2], data = presidential
)
p
p + scale_fill_manual(values = alpha(c("blue", "red"), .3))
The rectangles span each president's term, from the presidential table, coloured by party and
as tall as the range of unemployment. Giggly draws the first plot, the number unemployed each
month.
p =
economics
|> Plot.new(%{x: :date, y: :unemploy})
|> Plot.geom_line()
render.(p)
Not in Giggly yet: the presidential dataset, removing the plot's x and y from a layer's
mapping, R's aes(NULL, NULL), and colours made transparent by alpha().