I would like to pass values from an indexed vector into the expression()
function in ggplot. Easiest just to show what I mean. Here is toy data. Three groups each with 11 values.
# Toy data
data.frame(out = c(seq(0,1,.1), seq(0,0.5,.05), seq(0,0.1,.01)),
time = seq(0,50,5),
group = factor(rep(letters[1:3],each=11))) -> d
Now create a vector of counts of numbers in each group to pass into legend labels
groupCounts <- table(d$group)
groupCounts
# output
# a b c
# 11 11 11
Now to manually change legend colours and labels using scale_colour_manual()
. I want to pass the number for each group into an expression()
function that will render the corresponding label in the legend of the graph, like so
ggplot(data = d,
mapping = aes(x = time,
y = out,
colour = group)) +
geom_line() +
scale_colour_manual(labels = c(expression(paste("All (", italic("n"), "=", groupCounts[1], ")")),
expression(paste("0 days (", italic("n"), "=", groupCounts[2], ")")),
expression(paste("1-9 days (", italic("n"), "=", groupCounts[3], ")"))),
values = c("#440154",
"#31688E",
"#35B779"))
But the values from the indexed vector do not come out in the graph
When I just manually enter the numbers it works
ggplot(data = d,
mapping = aes(x = time,
y = out,
colour = group)) +
geom_line() +
scale_colour_manual(labels = c(expression(paste("All (", italic("n"), "=", 11, ")")),
expression(paste("0 days (", italic("n"), "=", 11, ")")),
expression(paste("1-9 days (", italic("n"), "=", 11, ")"))),
values = c("#440154",
"#31688E",
"#35B779"))
So how do I get the indexed vector values to show up as numbers in the legend labels?
Any help much appreciated
You can use bquote()
instead of expression()
:
library(ggplot2)
ggplot(data = d,
mapping = aes(x = time,
y = out,
colour = group)) +
geom_line() +
scale_colour_manual(labels = c(bquote(paste("All (", italic("n"), "=", .(groupCounts[1]), ")")),
bquote(paste("0 days (", italic("n"), "=", .(groupCounts[2]), ")")),
bquote(paste("1-9 days (", italic("n"), "=", .(groupCounts[3]), ")"))),
values = c("#440154",
"#31688E",
"#35B779"))
3
One possible solution is to use ggtext
and glue
library(glue)
library(ggtext)
library(dplyr)
library(ggplot2)
data.frame(out = c(seq(0,1,.1), seq(0,0.5,.05), seq(0,0.1,.01)),
time = seq(0,50,5),
group = factor(rep(letters[1:3],each=11))) -> d
nice_labs = d |>
mutate(counts = n(),
nice_labs = case_when(
group == 'a' ~ glue('All (*n* = {counts})'),
group == 'b' ~ glue('0 days (*n* = {counts}'),
group == 'c' ~ glue('1-9 days (*n* = {counts}')),
.by = group)
ggplot(nice_labs, aes(x = time, y = out, color = nice_labs)) +
geom_line() +
scale_color_manual(
values = c("#440154",
"#31688E",
"#35B779")) +
theme(legend.text = element_markdown())
Created on 2024-09-12 with reprex v2.1.0