Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically create expression for ggplot legend?

I want to plot a line graph, with multiple lines, coloured depending on a grouping variable. Now I want to set the legend labels via scale-command:

scale_color_manual(values = colors_values, labels = ...)

The legend labels are as following: "x^2", "x^3", "x^4" etc., where the range is dynamically created. I would now like to dynamically create the expression as label text, i.e.

  • "x^2" should become x2
  • "x^3" should become x3

etc.

The amount of legend labels varies, so I thought about something like as.expression(sprintf("x^%i", number)), which does of course not work as label parameter for the scale function.

I have searched google and stack overflow, however, I haven't found a working solution yet, so I hope someone can help me here.

Here's a reproducible example:

poly.term <- runif(100, 1, 60)
resp <- rnorm(100, 40, 5)
poly.degree <- 2:4
geom.colors <- scales::brewer_pal(palette = "Set1")(length(poly.degree))
plot.df <- data.frame()
for (i in poly.degree) {
  mydat <- na.omit(data.frame(x = poly.term, y = resp))
  fit <- lm(mydat$y ~ poly(mydat$x, i, raw = TRUE))
  plot.df <- rbind(plot.df, cbind(mydat, predict(fit), sprintf("x^%i", i)))
}
colnames(plot.df) <- c("x","y", "pred", "grp")
ggplot(plot.df, aes(x, y, colour = grp)) +
  stat_smooth(method = "loess", se = F) +
  geom_line(aes(y = pred))
  scale_color_manual(values = geom.colors
                     # here I want to change legend labels
                     # lables = expresion???
                     )

enter image description here

I would like to have the legend labels to be x2, x3 and x4.

like image 712
Daniel Avatar asked Sep 19 '26 23:09

Daniel


1 Answers

ggplot(plot.df, aes(x, y, colour = grp)) +
  stat_smooth(method = "loess", se = F) +
  geom_line(aes(y = pred)) +
  scale_color_manual(values = setNames(geom.colors,
                                       paste0("x^",poly.degree)),
                     labels = setNames(lapply(poly.degree, function(i) bquote(x^.(i))), 
                                       paste0("x^",poly.degree)))

It's important to ensure correct mapping if you change values or labels in the scale. Thus, you should always use named vectors.

resulting plot

like image 137
Roland Avatar answered Sep 21 '26 20:09

Roland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!