Search code examples
rggplot2labelplotmath

r label plots with fractions


I would like to create 3 plots each containing a plot of 2 lines from different data frames, and then label each plot with a specific fraction.

So for example I have the 3 data frames:

df1 <- data.frame(x=c(1,2,3,4),y=c(2,3,4,5), z=c(3,3,6,8))
df2 <- data.frame(x=c(3,4,5,6),y=c(1,3,6,7), z=c(2,4,4,8))
df3 <- data.frame(x=c(1,2,2,3),y=c(2,5,6,9), z=c(2,5,6,7))

And I would like to:

1) Create 3 different plots for each data frame, each with one red and one blue line;

2) Add an annotation over the blue line of each plot using a different fraction for each plot.

For example the plot for data frame 1 is something like this:

p1 <- ggplot(data = df1) + geom_line(aes(x=x,y=y, colour="blue")) + geom_line(aes(x=x,y=z, colour="red")) +  scale_colour_manual(name="data", values=c("red", "blue"))

Then to add the labels over the blue line I have tried:

p1 + geom_text(aes(x=df1$x[which.max(df1$y)]+1, y = max(df1$y)+4,  label = "{\frac{23 22 22}{44 28 32}}", size=2, parse=TRUE))

But this does not work, and I have searched so many hours and cannot find how to use fractions (and brackets enclosing the fraction) in the annotations. Any help is deeply appreciated!

-fra


Solution

  • It is not clear what do you want to have. This is an attempt;

    • I use mapply to loop over plots and fractions and generate a list of plots.
    • I create fractions using frac(x,y)
    • I set limits of plots using scale_y_continuous
    • I use gridExtra to arrange plots in the same plot (optional)

    enter image description here

    Here the complete code:

     ## a generic function that take a fraction ana a  data.frame as inputs
     ## it generate a plot
     plot.frac <- function(dat,frac){
         p <-  ggplot(dat) + 
               geom_line(aes(x=x,y=y, colour="blue")) + 
               geom_line(aes(x=x,y=z, colour="red")) +  
               scale_colour_manual(name="data", values=c("red", "blue"))+
               geom_text(x=dat$x[which.max(dat$y)]-0.05, y = max(dat$y)+4,  
                         label = frac, size=5,parse=TRUE)+
               ## Note the use of limits here to display the annotation 
               scale_y_continuous(limits = c(min(dat$y), max(dat$y)+5))
         p
        }
    ## create a list of data.frame of mapply    
    df.list <- list(df1,df2,df3)
    ## ggplot2 use plotmath so  for fraction you use frac(x,y)
    ## here I construct the 2 terms using paste
    frac.func <- function(num,den) paste('frac("',num,'","',den,'")',sep='')
    num1 <- "line1:23 22 22"
    den1 <- "line2: 44 28 32"
    num2 <- "line1:23 50 22"
    den2 <- "line2: 44 50 32"
    num3 <- "line1:23 80 22"
    den3 <- "line2: 44 80 32"
    ## create a list of fractions for mapply
    
    frac.list <- list(frac.func(num1,den1),
                  frac.func(num2,den2),
                  frac.func(num3,den3))
    frac.list <- list(frac,frac,frac)
    ## use mapply to call the plot over the 2 lists of data.frame and fractions
    ll <- mapply(plot.frac,df.list,frac.list,SIMPLIFY=FALSE)
    library(gridExtra)
    do.call(grid.arrange,ll)