expressions as annotations broken
Closed this issue · 12 comments
I think this is due to the recent update. It used to work.
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +
annotate("text", x = 3, y = 30, label = latex2exp::TeX("$\\alpha + \\beta x$"))
#> Error in `annotate()`:
#> ! Problem while setting up geom aesthetics.
#> ℹ Error occurred in the 2nd layer.
#> Caused by error in `list_sizes()` at ggplot2/R/geom-.R:518:3:
#> ! `x$label` must be a vector, not a <latexexpression/expression> object.Created on 2025-09-18 with reprex v2.1.1
Thanks for the report! The error message is correct, it should be a proper vector. Previously, the expressions were allowed by mistake. The parse argument should be used if the intent is to use an expression.
OK, but the parse argument doesn't seem to make any difference.
It seems latex2exp::TeX() can return characters by output = "character". It's a bit inconvenient, but I hope this works for you...
Thanks. In case anyone else has the same problem, the solution was a combination of these suggestions:
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
annotate(
"text",
x = 3,
y = 30,
label = latex2exp::TeX("$\\alpha + \\beta x$", output = "character"),
parse = TRUE,
size = 5
)Created on 2025-09-19 with reprex v2.1.1
Does anyone have a solution for axis labels?
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
annotate(
"text",
x = 3,
y = 30,
label = latex2exp::TeX("$\\alpha + \\beta x$", output = "character"),
parse = TRUE,
size = 5
) +
scale_x_continuous(breaks = 3, labels = TeX("$\\alpha$"))
yields
Error in
vec_size():
!xmust be a vector, not a <latexexpression/expression> object.
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
annotate(
"text",
x = 3,
y = 30,
label = latex2exp::TeX("$\\alpha + \\beta x$", output = "character"),
parse = TRUE,
size = 5
) +
scale_x_continuous(breaks = 3, labels = TeX("$\\alpha$", output = character), parse = TRUE)
yields:
Error in scale_x_continuous(breaks = 3, labels = TeX("$\alpha$", output = character), :
unused argument (parse = TRUE)
Thanks, confirmed. Could you file a new issue? It seems this is so tricky that I cannot immediately come up with a good fix.
The error happens here. key is a data frame containing a latexexpression object in .label column.
Line 287 in af6f4e8
The problem is, the latexexpression object cannot be subset by vec_slice() because
x <- as.list(latex2exp::TeX("$\\alpha$"))
vctrs::obj_is_vector(x)
#> [1] FALSEHowever, it works if the object doesn't have S3 classes.
vctrs::obj_is_vector(unclass(x))
#> [1] TRUESo, an easy workaround is to use unclass(). Or, you can simply use parse(text =) instead of latex2exp.
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
annotate(
"text",
x = 3,
y = 30,
label = latex2exp::TeX("$\\alpha + \\beta x$", output = "character"),
parse = TRUE,
size = 5
) +
scale_x_continuous(breaks = 3, labels = unclass(latex2exp::TeX("$\\alpha$")))Created on 2025-09-23 with reprex v2.1.1
Thanks for the report! The error message is correct, it should be a proper vector. Previously, the expressions were allowed by mistake. The
parseargument should be used if the intent is to use an expression.
This has to be the worst change ever.
This has to be the worst change ever.
And yet, we have no plans to revert it.
The book mentions quote
https://ggplot2-book.org/annotations.html
And use case I had to use at some point:
https://forum.posit.co/t/how-to-include-grouped-parenthesis-in-ggplot-geom-text/5645/2
And yet, we have no plans to revert it
However, plans change and now we want to allow expressions as label aesthetic.
And yet, we have no plans to revert it
However, plans change and now we want to allow expressions as
labelaesthetic.
My workaround has been to use expr_text() around expression() and bqoute(). Saved me from having to remake literally hundreds of graphs and figures.
for reference, here is an updated version of my code to plot (1) axis labels in scientific notation in 10^x format; (2) latitude-longitude labels. For a character vector v I had to change parse(text=v) to sapply(v, function(x) parse(text = x)) (it would be convenient if scale_[xy]_continuous got a parse argument ...)
https://gist.github.com/bbolker/5ba6a37d64b06a176e320b2b696b6733

