library(ggplot2)
# Emoji will not always render flawlessly with default device
::opts_chunk$set(dev = "ragg_png") knitr
Exercises for session 4
Ink & Paper
Exercise 4.1
We’ll work with this plot of the penguins dataset.
<- ggplot(palmerpenguins::penguins) +
p aes(body_mass_g, flipper_length_mm, shape = species) +
geom_point(na.rm = TRUE) +
labs(
x = "Body Mass (g)",
y = "Flipper Length (mm)",
shape = "Species"
) p
Pick any of the pre-existing complete themes and make a ‘dark mode’ variant of it.
+ ... p
Hint
Use the ink
and paper
arguments in —for example— theme_gray()
.
Solution
A different theme choice is fine, but the important bit is to set paper
to a dark colour and ink
to a light colour.
+ theme_gray(ink = "white", paper = "black") p
Default palettes
Exercise 4.2
This plot has a shape scale with the default palette.
<- ggplot(mpg, aes(displ, hwy, shape = fl)) +
p geom_point(size = 5) +
scale_shape_discrete(
breaks = c(
regular = "r",
ethanol = "e",
diesel = "d",
premium = "p",
CNG = "c"
)+
) labs(
x = "Engine Displacement",
y = "Fuel efficiency",
shape = "Fuel type"
) p
Make a discrete shape palette using emoji. You can pick a theme like ‘farm animals’, ‘bugs’, ‘flowers’ or other symbols. Set it as the default palette in the theme()
.
<- ...
my_shape_pal
+ theme(... = my_shape_pal) p
Hint
Shapes can use emoji because these count as ‘single letter’ strings. The palette can be a character vector that is compatible with scales::as_discrete_pal()
.
Solution
The important bit is to realise that one should populate the palette.shape.discrete
argument.
<- c("🫛", "🍓", "🥕", "🍋", "🍇")
my_shape_pal
+ theme(palette.shape.discrete = my_shape_pal) p
Build your own theme
Exercise 4.3
We have the following contour plot of eruption measurements taken from the geyser ‘Old Faithful’.
<- ggplot(faithful) +
p aes(waiting, eruptions) +
geom_density2d(bins = 8) +
geom_point() +
labs(
x = "Waiting time (min)",
y = "Eruption time (min)"
) p
Pick some topic that has a strong association with a colour scheme. It can be a forest, the ocean, the desert or something you come up with. Create your own theme with that topic in mind that:
- Is a function
- Passes arguments to a base theme
- Adjusts layer defaults
<- ...
my_theme
+ my_theme() p
Hint
You may want to pass an ink
/paper
/accent
argument to the base theme. Layer defaults can be set using element_geom()
.
Solution
This is more of an exercise without a ‘correct’ answer, but here is an example using the night sky as topic.
<- function(ink = "cornsilk", paper = "#000033", accent = "gold", ...) {
my_theme theme_gray(ink = ink, paper = paper, accent = accent, ...) +
theme(
geom = element_geom(pointshape = "\u2605", pointsize = 3, linewidth = 0.2)
)
}
+ my_theme() p
Custom guides
Exercise 4.4
We have the following unemployment data from the United States.
library(legendry)
<- ggplot(economics, aes(date, unemploy)) +
p geom_area(colour = "black", alpha = 0.3) +
labs(
x = "Date",
y = "Unemployment (x1000)"
)
p
Pick some event or period in the range of the plot above. Create an axis annotation to indicate that event or period. You may need to construct the appropriate key
argument for a custom guide.
<- ...
my_annotation
+ guides(x = compose_stack("axis", my_annotation)) p
Hint 1
If you’re stuck without inspiration, here are some arbitrary events and periods:
- First release of ggplot2 (2007)
- Margaret Thatcher serves as the UK’s prime minister (1979-1990)
- Release of the original Sony Walkman (1979)
- The pop group ‘The Spice Girls’ (1994-2000)
- Fall of the Berlin Wall (1989)
- Release of the pinnacle of telecommunication, the Nokia 3310 (2000)
- The British sitcom ‘Mr. Bean’ (1990-1995)
- Thomas Lin Pederson was born (1985)
- David Tennant plays the 10th Doctor in ‘Doctor Who’ (2005-2010)
- The American sitcom ‘Golden Girls’ (1985-1992)
- The birth of Hadley Wickham (1979)
- Texas Instruments launches its first graphing calculator (1990)
Hint 2
You can combine legendry::primitive_bracket()
+ legendry::key_range_manual()
for periods. You can use legendry::guide_axis_base()
+ legendry::key_manual()
for point-events.
Solution
For a range of dates:
<- primitive_bracket(
my_annotation key = key_range_manual(
start = as.Date("1977-01-20"),
end = as.Date("1981-01-20"),
name = "Carter administration"
),bracket = "square"
)
+ guides(x = compose_stack("axis", my_annotation)) p
For an event:
<- guide_axis_base(
my_annotation key = key_manual(
aesthetic = as.Date("1991-09-27"),
label = "Release 'Terminator 2'"
),theme = theme(
axis.ticks.length = unit(6, "mm"),
axis.ticks = element_line(arrow = arrow(length = unit(1.5, "mm")))
)
)
# Swapping the composition is a little bit cheating on my end
+ guides(x = compose_ontop("axis", my_annotation)) p