0

I am trying to generate plots from a variable number of arguments. The code works fine and generates the intended plots. However, the labels function (fill = labels[i]) does not work as intended. I can't figure out what I did wrong here. All the lines have the same label "C 3" and therefore have the same color.

library(ggplot2)
F.Linear <- function(A, a, b, c) {
    C <- (c - a*A)/b
    C[C < 0] <- NA
    return(C)
}

plot.linear.equations <- function(X, ...){
p <- ggplot(data.frame(x = X), aes(x = x))

  arguments <- list(...)

  mycolors <- c("red", "blue", "green", "orange")
  labels <- c("C 1", "C 2", "C 3", "C 4")

  for(i in 1:length(arguments)){
    C <- unlist(arguments[i])
    p <- p + stat_function(fun=F.Linear, args = list(a=C[1], b=C[2], c=C[3]), geom="area", colour="black", alpha=0.2, aes(fill = labels[i]))
  }
  p <-  p +   scale_x_continuous(name = "A") +
    scale_y_continuous(name = "C") +
    scale_fill_manual("Constraints", values = c("red", "blue", "green", "orange"))
return(p)
}

C1 <- c(12, 6, 20400)
C2 <- c(9, 15, 25200)
C3 <- c(6, 6, 12000)


plot.linear.equations(c(0, 3000), C1, C2, C3)

enter image description here

max
  • 1,692
  • 5
  • 28
  • 40
  • 2
    Possible duplicate of [ggplot2: adding lines in a loop and retaining colour mappings](https://stackoverflow.com/questions/32698616/ggplot2-adding-lines-in-a-loop-and-retaining-colour-mappings) – aosmith Sep 05 '17 at 16:30
  • I understand that the problem looks similar, however, I could not use the trick on the linked question (using cbind to add the variable to data). Still trying to figure out. – max Sep 05 '17 at 17:41
  • No, this is my exact code. I did not do X$labels = labels[1]. In the linked example, they used data column, but I have not data column in stat_function. Still trying to figure out. I know, if I write it as a whole instead of loop, it will work. But I want to figure out why the loop does not work. – max Sep 05 '17 at 17:57

1 Answers1

1

As shown in the duplicate, moving the labels to the dataset bypasses the issue of delayed evaluation in aes.

You can do this by first making a dataset in the function and adding the appropriate labels value to it within the loop as a new variable in the dataset. You can use this dataset for the data argument ofstat_function.

plot.linear.equations <- function(X, ...){
     dat <- data.frame(x = X)

     p <- ggplot(mapping = aes(x = X))

     arguments <- list(...)

     mycolors <- c("red", "blue", "green", "orange")
     labels <- c("C 1", "C 2", "C 3", "C 4")

     for(i in 1:length(arguments)){
          dat$label <- labels[i]
          C <- unlist(arguments[i])
          p <- p + stat_function(data = dat, fun=F.Linear, args = list(a=C[1], b=C[2], c=C[3]), geom="area", colour="black", alpha=0.2, aes(fill = label))
     }

     p <-  p + scale_x_continuous(name = "A") +
          scale_y_continuous(name = "C") +
          scale_fill_manual("Constraints", values = c("red", "blue", "green", "orange"))
     return(p)
}

enter image description here

aosmith
  • 34,856
  • 9
  • 84
  • 118