TeeVee
TeeVee

Reputation: 1

Plotting multiple equations in R with equation labels, using ggplot2

I'm trying to plot multiple equations using geom_function() in ggplot2, and label them using equations formatted using latex2exp. The problem is that the order is not preserved when I use scale_color_discrete() to add the equations to the legend. I can reverse the order in labels input to scale_color_discrete(), but is there a more clever way to add these labels?

library(ggplot2)
library(latex2exp)

ggplot() +
  geom_function(
    fun = function(x) {5^x}, 
    aes(color="red"), 
    lwd=1) +
  geom_function(
    fun = function(x) {10^x}, 
    aes(color="blue"),
    lwd=1) +
  scale_color_discrete(labels=c(TeX("$f(x)=5^x$"), TeX("$f(x)=10^x$"))) + 
  xlim(-1, 5)

enter image description here

Upvotes: 0

Views: 56

Answers (2)

denis
denis

Reputation: 5673

Using your code, the propoer way would be:

ggplot() +
  geom_function(
    fun = function(x) {5^x}, 
    aes(color="fun1"), 
    lwd=1) +
  geom_function(
    fun = function(x) {10^x}, 
    aes(color="fun2"),
    lwd=1) +
  scale_color_manual(breaks = c("fun1","fun2"),
                     labels=c(TeX("$f(x)=5^x$"), TeX("$f(x)=10^x$")),
                     values = c("red","blue")) + 
  xlim(-1, 5)

You don't set the color un aes, you set the group color for the legend.

If you have a lot of function to draw, I think you better do it by hand without geom_function, as it will be more concise: you can actively use the long format


xaxis <- seq(-1,5,.1)
powers <- c(2,4,5,8,10)
df <- data.frame(x = rep(xaxis,length(powers)),exp = rep(powers,each = length(xaxis)))
df <- df %>%
  group_by(exp)%>%
  mutate(y = exp^x)

ggplot(df,aes(x,y,color = as.factor(exp),group = exp))+
  geom_line(linewidth = 1)+
  scale_color_manual(breaks = powers,
                     labels =lapply(paste0("$f(x)=",powers,"^x$"),TeX) %>% unlist(),
                     values = viridis(length(powers)))


enter image description here

Upvotes: 0

PBulls
PBulls

Reputation: 1731

First off, setting aes(color="red") probably does not have the effect you intend: it does not actually assign the color red to that geom. It rather creates a "color group" with the identifier "red", the actual color will be assigned by scale_color_discrete. Try changing your current color assignments to other (unique) values: they will not make any difference.

The simple solution to link the groups and the labels is to name the latter by the identifiers you've given in the aes call:

scale_color_discrete(labels=c("red"=TeX("$f(x)=5^x$"), "blue"=TeX("$f(x)=10^x$")))

The reason they end up in the wrong order as you've specified them now is that unnamed values are assigned in alphabetical order, and blue comes before red.

Still note that the red-ish and blue-ish colors are the defaults of scale_color_discrete: changing these in the aes will not actually produce different colors. To overcome that you have at least two options:

  • set color= directly within the geom, not inside an aes. This will break the link with scale_color_... and you will have to recreate the legend.
  • much easier: switch to scale_color_manual and combine that with values=. For example, values=c("red"="orange", "blue"="green") will actually give you orange & green lines (the aes names also being colors makes this a bit confusing).

Upvotes: 0

Related Questions