Reputation: 1074
Closest I've come is here:
Annotate ggplot plot with a multiline expression with objects?
but I cannot seem to get the solution working. I cannot use the ggpmisc
package because I am forcing the regression through the origin. Here's some example data to create a plot and the exact expressions I am working with.
library(tidyverse)
df <- tibble(x=rnorm(10,10,3),
y=rnorm(10,10,3)+exp(seq(1,10,1)))
eqn <- "italic(y) == \"53\" * italic(x) * \",\" ~ ~italic(r)^2 ~ \"=\" ~ \"0.732\""
a <- "italic(y) == \"53\" * italic(x)"
r2 <- "italic(r)^2 == \"0.732\""
This works for a single line:
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggplot2::annotate('text',
x = 0, y = 15000,
label=a,
parse = T,
hjust=-1)
This does not work:
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggplot2::annotate('text',
x = 0, y = 15000,
label=paste(a,r2),
parse = T,
hjust=-1) # throws error
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggplot2::annotate('text',
x = 0, y = 15000,
label=paste(a,r2,sep='\n'),
parse = T,
hjust=-1) # no error but no R2 value
Per the linked solution I should be able to use atop()
inside the expression?
This throws an error:
# from solution linked that I'm trying to adapt
# paste0('atop(Q[10] ==', q10, ', M[O[2]] ==', a, '*e^(', b, '*T))')
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggplot2::annotate('text',
x = 0, y = 15000,
label=paste0('atop(y ==', a, ', r^2 ==', r2, '*e^2)'),
parse = T)
hjust=-1)
Upvotes: 0
Views: 703
Reputation: 66415
Here's a ggtext alternative:
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggtext::geom_richtext(aes(x,y, label = label),
hjust = 0,
data = data.frame(x = 0, y = 15000,
label = "53*x*<br>*r<sup>2</sup>* = 0.732"))
We could automate it like this:
set.seed(42)
df <- tibble(x=rnorm(10,10,3),
y=rnorm(10,10,3)+exp(seq(1,10,1)))
fit <- lm(y~x, df)
r2 <- formatC(summary(fit)$r.squared, digits = 2)
slope <- formatC(fit$coefficients[2], digits = 2)
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggtext::geom_richtext(aes(x,y, label = label),
hjust = 0,
data = data.frame(x = 0, y = 15000,
label = paste0(slope, "*x*<br>*r<sup>2</sup>* = ", r2)))
Suggested edit from the original poster:
To account for forcing the regression through the origin, first with the full formula when it is not forced through (0,0), then with just the slope when it is. Because the above would not make sense to someone else (why only provide the slope of the regression?
set.seed(42)
df <- tibble(x=rnorm(10,10,3),
y=rnorm(10,10,3)+exp(seq(1,10,1)))
fit <- lm(y~x, df)
r2 <- formatC(summary(fit)$r.squared, digits = 2)
slope <- formatC(fit$coefficients[2], digits = 2)
int <- formatC(fit$coefficients[1], digits = 2)
eqn <- formatC(paste(int,"+",slope))
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggtext::geom_richtext(aes(x,y, label = label),
hjust = 0,
data = data.frame(x = 0, y = 15000,
label = paste0(eqn, "*x*<br>*r<sup>2</sup>* = ", r2)))
# Force regression through origin
fit0 <- lm(y~0+x,df)
r20 <- formatC(summary(fit)$r.squared, digits = 2)
slope0 <- formatC(fit0$coefficients[1], digits = 2) # only a slope coefficient
# int0 <- 0
# eqn0 <- slope0 # these are not necessary because the regression goes through the origin
ggplot(df) +
geom_point(aes(x=x,y=y)) +
ggtext::geom_richtext(aes(x,y, label = label),
hjust = 0,
data = data.frame(x = 0, y = 15000,
label = paste0(slope0, "*x*<br>*r<sup>2</sup>* = ", r2)))
Upvotes: 3