This article contains some recipes for different plot styles and how to apply waratah styles. Each example shows the base plot then the themed version.
Example 1: markdown text
With standard ggplot output:
library(waratah)
library(palmerpenguins)
library(ggplot2)
library(dplyr)
long_text <- paste(
c(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do",
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim",
"ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut",
"aliquip ex ea commodo consequat."
),
collapse = " "
)
p1 <-
ggplot(penguins) +
geom_point(aes(
x = bill_length_mm,
y = flipper_length_mm,
colour = species,
size = body_mass_g
)) +
labs(
title = "Let's try some *italics* in the title",
subtitle = long_text,
dictionary = c(
bill_length_mm = "Bill length (mm)",
flipper_length_mm = "Flipper length (mm)",
species = "Species",
body_mass_g = "Body mass (g)"
),
caption = "Data from {palmerpenguins}"
)
p1
#> Warning: Removed 2 rows containing missing values or values outside the scale range
#> (`geom_point()`).
Style with waratah:
p1 +
theme_waratah()
#> Warning: Removed 2 rows containing missing values or values outside the scale range
#> (`geom_point()`).
Change to a different NSW palette:
p1 +
scale_colour_discrete(palette = pal_waratah("qual", var = "aboriginal")) +
theme_waratah()
#> Warning: Removed 2 rows containing missing values or values outside the scale range
#> (`geom_point()`).
The markdown handling is done with ggtext. See
vignette("theme_elements", package = "ggtext") for
details.
Example 2: grouped points
With standard ggplot output:
p2 <-
filter_out(penguins, is.na(sex)) |>
ggplot() +
geom_point(
aes(
x = bill_length_mm,
y = bill_depth_mm,
fill = interaction(sex, species),
),
shape = 21,
size = 3,
colour = "black",
alpha = 0.8
) +
labs(
title = "Penguin bill dimensions",
subtitle = "Separated by *species* and *sex*",
dictionary = c(
bill_length_mm = "Bill length (mm)",
bill_depth_mm = "Bill depth (mm)"
),
caption = "Data from {palmerpenguins}"
) +
guides(
fill = legendry::guide_legend_group(
title = NULL,
ncol = 1,
direction = "horizontal",
override.aes = list(size = 3)
)
)
p2 + scale_fill_brewer(palette = "Paired")
Styling using waratah package - here we want a paired colour palette:
p2 +
discrete_scale("fill", palette = pal_waratah("pairs")) +
theme_waratah()
More manual control of the palette is possible, for example specifying the rows and columns of the colour grid to use:
p2 +
scale_fill_discrete(
palette = pal_nsw(
t = 2:3,
h = c("purple", "blue", "red"),
var = "aboriginal"
)
) +
theme_waratah(base_size = 14)
Example 3: stacked bars
With standard ggplot output
p3 <-
filter_out(penguins, is.na(sex)) |>
ggplot(aes(x = species, fill = island)) +
geom_bar() +
labs(
dictionary = c(species = "Species", island = "Island"),
title = "Perfectly proportional penguins",
subtitle = "Where do they all live?",
caption = "Data from {palmerpenguins}"
) +
facet_wrap(vars(sex))
p3
Styling using the waratah package - specifying pallete
p3 +
scale_fill_discrete(palette = pal_nsw(hue = "purples")) +
theme_waratah(base_size = 14) +
guides(x = guide_axis(angle = 70)) +
theme(panel.grid.major.x = element_blank())
Example 4: doughnut
With standard ggplot output:
p4 <-
ggplot(penguins) +
geom_bar(aes(1, fill = species)) +
geom_text(
aes(
1,
y = after_stat(count),
label = stage(
species,
after_stat = sprintf("%s\n%.0f%%", label, 100 * count / sum(count))
),
colour = stage(
species,
after_scale = col_contrasting(colour)
)
),
stat = "count",
position = position_stack(vjust = .5),
show.legend = FALSE
) +
coord_radial(
theta = "y",
inner.radius = .5,
expand = FALSE,
rotate.angle = TRUE
) +
labs(
title = "Does anyone know if penguins like doughnuts?",
subtitle = "Not sure, but we know there are three species in the dataset",
caption = "Data from {palmerpenguins}"
)
p4
Styling using the waratah package with options:
p4 +
scale_fill_discrete(
aesthetics = c("fill", "colour"),
palette = pal_waratah("qual"),
guide = "none"
) +
theme_waratah(
void = TRUE,
base_size = 14
)
Example 5: Likert scale
Likert-scale survey responses can be handled with dedicated tools
like ggstats::gglikert(). Here is a self-contained ggplot
stat that achieves a limited version of the same result for the purposes
of demonstrating styling.
StatLikert <- ggproto(
"StatLikert",
StatIdentity,
compute_layer = function(self, data, params, layout) {
mutate(
data,
offset = sum(x[1:(n() %/% 2)]),
offset = if_else(
rep(n() %% 2 > 0, n()),
offset + x[n() %/% 2 + 1] / 2,
offset
),
left = cumsum(lag(x, default = 0)) - offset,
right = cumsum(x) - offset,
x = (left + right) / 2,
width = right - left,
.by = y
)
}
)With standard ggplot output:
sentiment <- c(
"Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"
)
survey_data <- tibble(
answer = factor(rep(sentiment, 2), levels = sentiment, ordered = TRUE),
percent = c(8, 12, 30, 40, 10, 6, 18, 24, 34, 18),
group = sort(rep(c("Male", "Female"), 5))
)
p5 <-
ggplot(
survey_data,
aes(x = percent, y = group, fill = answer)
) +
geom_vline(aes(xintercept = 0, colour = from_theme(accent))) +
# note: likert is not a standard stat - it's defined above
geom_tile(stat = "likert", height = 0.8) +
labs(
title = "Let's find out!",
subtitle = "How much do they agree with the statement \"Doughnuts are delicious\"?",
caption = "Totally made up data!",
x = NULL,
y = NULL,
fill = "Answer"
) +
theme(
panel.grid.major.y = element_blank(),
legend.position = "bottom"
) +
scale_x_continuous(labels = function(x) paste0(abs(x), "%"))
p5 + scale_fill_brewer(palette = "PiYG")
Styling using the waratah package. Note that the diverging palette is
continuous, so we need pal_stretch() to discretise it here.
We specify "red" as our starting hue. Without
cvd = TRUE the second colour ends up being green.
p5 +
discrete_scale(
"fill",
palette = pal_waratah("div", "red", cvd = TRUE) |> pal_stretch(),
breaks = sentiment
) +
theme_waratah(base_size = 12)