I want to use a subscript and a number in a geom_text()
layer of a ggplot2 plot. The number will come from an indexed dataframe so that I can use it in a flexible way within a custom function, but here is a simpler reproducible example:
temp_line <- structure(list(x = c(670.892544634835, 670.94367492675, 670.994805218665,
671.04593551058, 671.097065802495, 671.14819609441, 671.199326386325,
671.25045667824, 671.301586970155, 671.35271726207, 671.403847553985,
671.4549778459, 671.506108137815, 671.55723842973, 671.608368721645,
671.65949901356, 671.710629305475, 671.76175959739, 671.812889889305,
671.86402018122, 671.915150473135, 671.96628076505, 672.017411056965,
672.06854134888, 672.119671640795, 672.17080193271, 672.221932224625,
672.27306251654, 672.324192808455, 672.37532310037, 672.426453392285,
672.4775836842, 672.528713976115, 672.57984426803, 672.630974559945,
672.68210485186), y = c(0.985240554809607, 0.982213133032921,
0.986693753084667, 0.987366974516756, 0.987636649598203, 0.982056033377924,
0.980484643703154, 0.983029322815495, 0.988833379596215, 0.983723421126925,
0.984861430761356, 0.975375941059582, 0.973793277004997, 0.974896425651856,
0.976215113076567, 0.980190883847887, 0.97234555785344, 0.976564419204803,
0.971411825270084, 0.958092987035761, 0.948933680537213, 0.944433555718954,
0.955207036644352, 0.966236032356096, 0.97461001903587, 0.982502838158965,
0.977806030386617, 0.980102357820749, 0.971970360584438, 0.972510182292617,
0.971868273995148, 0.986332867356837, 0.992939055558675, 1, 0.990384208442822,
0.987140151281311)), class = "data.frame", row.names = c(NA,
-36L))
temp <- structure(list(x = 671.96628076505, y = 0.943555524955473), class = "data.frame", row.names = "window_mins")
temp_num <- c(window_mins = 0.000878030763480352)
# Attempt at plotting equation using paste()
ggplot() +
geom_line(data = temp_line,
aes(x = x, y = y), alpha = 0.85, size = 0.6) +
geom_point(data = temp,
aes(x = x, y = y), alpha = 0.85, size = 1.5, shape = 15) +
geom_text(data = temp,
aes(x = x, y = y),
label = paste("L1 - L[tot] = ",
formatC(temp_num,
format = "e", digits = 3)),
nudge_x = -0.45,
show.legend = FALSE)
The challenge is using paste()
in a way that works for both the subscript and the formatted number. I tried using expression()
and paste()
together. This creates the correct subscript, but unfortunately prints the command and arguments for formatC()
instead of evaluating to produce the number:
label = expression(paste("L1 - ", L[tot], "= ",
formatC(temp_num,
format = "e", digits = 3)))
I tried the above but wrapping the formatC
command in eval()
but I couldn't get that to work. I also played around with wrapping the whole expression in parse()
and substitute()
based on the links below. What am I missing to generate both a subscript and a formatted number within a paste()
command?
Related posts I looked at: Combining paste() and expression() functions in plot labels
https://community.rstudio.com/t/use-bquote-in-ggplot2-for-subscript-text/40882
R - how to combine expression(), paste() and formatC() commands for one legend element?
OK, this was surprisingly tricky.
First of all, you need to study help("plotmath")
. Then, I would pass a character string and let ggplot2 parse it. If we do that, the RHS of the equation should be specified as a character string, otherwise standard print formatting will be applied within plotmath. I prefer sprintf
for convenience but if you insist you can construct the same character string with a combination of paste
and formatC
.
#note the single quotes within the string
sprintf("L1 - L[tot] == '%.3e'", temp_num)
#[1] "L1 - L[tot] == '8.780e-04'"
ggplot() +
geom_line(data = temp_line,
aes(x = x, y = y), alpha = 0.85, size = 0.6) +
geom_point(data = temp,
aes(x = x, y = y), alpha = 0.85, size = 1.5, shape = 15) +
geom_text(data = temp,
aes(x = x, y = y),
label = sprintf("L1 - L[tot] == '%.3e'", temp_num),
nudge_x = -0.45,
show.legend = FALSE,
parse = TRUE)