This vignette demonstrates some of the use cases for curved text in ggplot.
Covid effects on life activities
After a design by George Stilabower
Data code block
df <- structure(list(xvals = rep(0:25, each = 13), yvals = c(
9, 0, 0, 2, 0, 9, 10, 13, 0, 0, 0, 0, 0, 9, 0, 0, 2, 0, 9,
10, 13, 0, 0, 0, 0, 0, 9, 0, 1, 0, 4, 6, 10, 0, 13, 0, 0, 0,
0, 6, 3, 1, 0, 0, 10, 10, 0, 13, 0, 0, 0, 0, 6, 3, 1, 0, 0, 10,
10, 0, 13, 0, 0, 0, 0, 9, 0, 1, 0, 4, 6, 10, 0, 13, 0, 0, 0,
0, 9, 0, 1, 0, 4, 6, 10, 0, 13, 0, 0, 0, 0, 9, 0, 0, 2, 0, 9,
10, 0, 13, 0, 0, 0, 0, 9, 0, 0, 2, 0, 9, 10, 0, 13, 0, 0, 0,
0, 6, 3, 1, 0, 0, 10, 10, 0, 0, 13, 0, 0, 0, 3, 6, 1, 0, 0, 10,
10, 0, 0, 13, 0, 0, 0, 9, 0, 1, 0, 4, 6, 10, 0, 0, 13, 0, 0,
0, 9, 0, 0, 2, 0, 9, 10, 0, 0, 13, 0, 0, 0, 9, 0, 1, 0, 4, 6,
10, 0, 0, 13, 0, 0, 0, 6, 3, 1, 0, 0, 10, 10, 0, 0, 13, 0, 0,
0, 9, 0, 0, 2, 0, 9, 10, 0, 0, 13, 0, 0, 0, 9, 0, 0, 2, 0, 9,
10, 0, 0, 0, 13, 0, 0, 9, 0, 0, 2, 0, 9, 10, 0, 0, 0, 13, 0,
0, 9, 0, 0, 2, 0, 9, 10, 0, 0, 0, 0, 13, 0, 9, 0, 0, 2, 0, 9,
10, 0, 0, 0, 0, 13, 0, 9, 0, 1, 0, 4, 6, 10, 0, 0, 0, 0, 0, 13,
6, 3, 1, 0, 0, 10, 10, 0, 0, 0, 0, 0, 13, 9, 0, 0, 2, 0, 9, 10,
0, 0, 0, 0, 0, 13, 9, 0, 0, 2, 0, 9, 10, 0, 0, 0, 0, 0, 13, 9,
0, 0, 2, 0, 9, 10, 0, 0, 0, 0, 0, 13, 9, 0, 0, 2, 0, 9, 10, 0,
0, 0, 0, 0, 13)/20,
cols = structure(c(13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L,
1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L,
12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L,
11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L,
10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L,
9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L,
7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L,
5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L,
3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L,
1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L,
12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L,
11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L,
10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L,
9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L,
7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L,
5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L,
3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L,
1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L,
12L, 11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L,
11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L,
10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L,
9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L,
7L, 6L, 5L, 4L, 3L, 2L, 1L, 13L, 12L, 11L, 10L, 9L, 8L, 7L, 6L,
5L, 4L, 3L, 2L, 1L), .Label = c("Nesting Variable 6", "Nesting Variable 5",
"Nesting Variable 4", "Nesting Variable 3", "Nesting Variable 2",
"Nesting Variable 1", "blank", "mint", "green", "darkgray", "lightgray",
"red", "pink"), class = "factor")),
class = "data.frame", row.names = c(NA, -338L))
df_text <- data.frame(x = rep(0:25, each = 2)[-c(3:4)] + 0:1 -0.5,
y = 1.25, id = rep(0:25, each = 2)[-c(3:4)],
text = rep(c(
"<strong>Total</strong>", "ipad", "Visits", "Parties", "Walks", "Home\nSchool", "Games",
"Meals", "SPA", "Research", "HDU",
"Meetings", "Admin", "Breaks", "Ward\nRounds", "Car", "Train", "Family", "Friends", "Github", "SO", "Docs", "Issues", "Debug",
"Side\nProjects"), each = 2))
label1 <- paste("Family activities:",
"These tended to increase",
"during lockdown, but the",
"types of activity",
"changed.", sep = "\n")
label2 <- paste("Work activities:",
"These were due",
"directly to the",
"medical effects",
"of the pandemic.", sep = "\n")
label3 <- paste("Coding activities:",
"These tended to increase",
"during lockdown, but",
"the focus changed",
"depending on the",
"needs of side",
"projects.", sep = "\n")
fills <- rev(c("#e9cbc1", "#b54649", "gray90",
"gray50", "#8ba55d", "#e2e4d6",
"white", "#c3a891", "#37959d",
"#5c7890", "#dcad3c", "#55a3b9",
"#f39068"))
sep <- c(1.5, 8.5, 15.5, 17.5, 19.5)
sublabels <- data.frame(x = c(-0.25, 1.5, 2, 6, 9, 15, 16, 18, 18, 20, 20, 25),
y = 1.8,
id = c(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5),
z = rep(c("Sleeping", "Family", "Work",
"Travel", "Social", "Coding"), each = 2))
covidpie <- list(df = df, df_text = df_text, fills = fills,
label1 = label1, label2 = label2, label3 = label3,
sep = sep, sublabels = sublabels)
ggplot(covidpie$df, aes(xvals, yvals)) +
geom_col(width = 1.05, aes(fill = cols)) +
geom_vline(colour = "white", xintercept = sep, size = 3) +
geom_segment(data = data.frame(x = 0.5 + 1:24, y = 0, yend = 1),
aes(x = x, y = 0, yend = 1, xend = x), colour = "white",
inherit.aes = FALSE) +
geom_textpath(data = covidpie$sublabels,
mapping = aes(x, y, label = z, group = id), size = 3.8,
upright = FALSE, text_only = TRUE, hjust = 0,
color = "white", family = "Times New Roman") +
geom_text(x = 32, y = -2, label = "Activities", check_overlap = TRUE,
size = 7, family = "Times New Roman") +
geom_text(x = 32, y = -1.4, label= "Changing time allocations\ndue to Covid",
lineheight = 1, check_overlap = TRUE, family = "Times New Roman") +
geom_textpath(data = covidpie$df_text, aes(x, y, label = text),
upright = FALSE, size = 2, rich = TRUE, text_only = TRUE,
halign = "left") +
geom_text(x = 36.5, y = 1.8, label = covidpie$label1, hjust = 0,
size = 2, check_overlap = TRUE, vjust = 1) +
geom_text(x = 32.8, y = 0.75, label = covidpie$label2, vjust = 1, hjust = 0,
size = 2, check_overlap = TRUE) +
geom_text(x = 28.8, y = 1.04, label = covidpie$label3, hjust = 0,
size = 2, check_overlap = TRUE, vjust = 1) +
scale_y_continuous(limits = c(-2, 2.2)) +
scale_fill_manual(values = covidpie$fills) +
scale_x_continuous(expand = c(0.2, 1)) +
coord_polar(start = -pi) +
theme_void() +
theme(legend.position = "none")
#> Warning: position_stack requires non-overlapping x intervals
Planetary orbits
set.seed(1)
planets <- c("Jupiter", "Saturn", "Uranus", "Neptune")
t <- seq(0, pi * 2, len = 500)
AU <- c(5.203, 9.539, 19.18, 30.06)
df <- data.frame(x = as.vector(outer(cos(t), AU)),
y = as.vector(outer(sin(t), AU)),
Planet = rep(planets, each = 500),
position = rep(c(0.75, 0.2, 0.4, 0.1)))
ggplot(df, aes(x, y, color = Planet)) +
geom_point(inherit.aes = FALSE,
data = data.frame(x = runif(1000, -30, 30),
y = runif(1000, -30, 30),
intens = runif(1000)/2),
mapping = aes(x, y, alpha = intens), color = "white", size = 0.2) +
geom_textpath(aes(label = Planet), linewidth = 0.3,
hjust = rep(c(0, 0.25, 0.75, 1), each = 500),
vjust = 1.1, size = 5, upright = TRUE, fontface = 2) +
geom_point(data = df[c(170, 600, 1385, 1965),], size = c(4, 3.5, 1.5, 1.5)) +
geom_point(x = 0, y = 0, size = 5, color = "#FFFFA0", inherit.aes = FALSE) +
scale_alpha_identity() +
scale_color_manual(values = c(Jupiter = "orangered",
Uranus ="violet",
Neptune = "skyblue",
Saturn = "gold")) +
coord_equal() +
theme_void() +
theme(plot.background = element_rect(fill = "black"),
legend.position = "none")