0
votes

I try to plot multiple graphs on the same plot using ggplot2. Any idea how to do that? I got a function called draw.data, which I use in R to draw the curve and this uses ggplot. I want to know if there's any parameter I can set as TRUE to force ggplot to draw the next graph on the same window by the next call of the function draw.data.

Here is the code:

draw.data <- function(xy){
  # Bibliothek für ggplot-Funktion
  # Dependencies: > library("ggplot2") must be imported!

  x.lab <- "concentration [M]"
  y.lab <- "normalised luminescence [%]"

  my.data <- data.frame(xy)

  my_labels <- parse(text = paste("1E", seq(-10, -4, 1), sep = ""))

  # Find max, min and difference
  # y.max <- max(my.data$y)
  # y.min <- min(my.data$y)

  y.max <- 1
  y.min <- 0

  diff <- y.max - y.min

  # Find percentage and apply to new column 
  my.data$y <- apply(my.data, 1, function(z) ((z["y"] - y.min)/diff)*100)

  ggp.temp <- ggplot(my.data, aes(x,y)) +
    #geom_point(aes(x = x, y = y, color = as.factor(x))) +
    #geom_point(aes(x = x, y = y)) +
    #geom_line(aes(x = x, y = y)) +
    #geom_line(aes(x = x, y = y, color = as.factor(x))) +
    geom_line() +
    # Draw 2 lines at 50% and 90% through the y-axis
    geom_hline(yintercept = c(50, 90), linetype = "dotted") + # draw dotted horizontal lines at 50 and 90
    scale_x_continuous(x.lab, breaks = seq(-10, -4, 1), labels = my_labels) + 
    labs(title = "Graph", x = x.lab, y = y.lab)

  return (ggp.temp)
}

And here is how I would like the plot to look like.

enter image description here

        x          y
 [1,] -10 1.14259527
 [2,]  -9 1.15024188
 [3,]  -8 1.10517450
 [4,]  -7 1.00961311
 [5,]  -6 0.71238360
 [6,]  -5 0.20355333
 [7,]  -4 0.04061895
 [8,] -10 1.11022461
 [9,]  -9 1.11083317
[10,]  -8 1.07867942
[11,]  -7 0.98422000
[12,]  -6 0.73539660
[13,]  -5 0.36134577
[14,]  -4 0.18124645
[15,] -10 2.13212408
[16,]  -9 1.14529425
[17,]  -8 1.25102307
[18,]  -7 1.16045169
[19,]  -6 0.50321380
[20,]  -5 0.15422609
[21,]  -4 0.10198811

[1,] -10 1.16539392
[2,]  -9 1.15855333
[3,]  -8 1.11766975
[4,]  -7 0.97204379
[5,]  -6 0.53504417
[6,]  -5 0.17431435
[7,]  -4 0.29470416
[8,] -10 1.03683145
[9,]  -9 1.07524250
[10,]  -8 1.07761291
[11,]  -7 0.96401682
[12,]  -6 0.78346457
[13,]  -5 0.32783725
[14,]  -4 0.08103084
[15,] -10 0.81372339
[16,]  -9 0.85402909
[17,]  -8 0.86584396
[18,]  -7 0.80705470
[19,]  -6 0.53086151
[20,]  -5 0.15711034
[21,]  -4 0.11496499
2
A minimal reproducible example would be nice. - Jaap
As Jaap set, it would have been nice to have example data ("reproducible"). However, I fear that's not how ggplot work. You are thinking along the lines of standard graphics in R, where you can plot the first line and axis, and add more curves with line. - Dieter Menne
You have to find a way to combine your datasets (rbind) in bigger one and create a grouping variable/column like "plot id". Then use ggplot with color=plot id, to plot all of them in the same graph. As Dieter said, ggplot has a different philosophy that the classical graphs. - AntoniosK
I just edited the question with some data... Hope this can help. Thanks - Lycone
@Lycone Did you read the link that Jaap posted? Please provide easily copy-paste-able data, e.g. dput it. - Henrik

2 Answers

0
votes

As mentioned in the comments, gpplot works by adding different layers to a plot. In order to achieve what you want, you should adapt your function like this:

draw.data <- function(xy, add = FALSE) {
    x.lab <- "concentration [M]"
    y.lab <- "normalised luminescence [%]"
    my.data <- data.frame(xy)
    my_labels <- parse(text = paste("1E", seq(-10, -4, 1), sep = ""))
    y.max <- 1
    y.min <- 0
    diff <- y.max - y.min
    my.data$y <- apply(my.data, 1, function(z) ((z["y"] - y.min)/diff)*100)
    if (!add) {
        ggplot(my.data, aes(x,y)) +
          geom_line() +
          geom_hline(yintercept = c(50, 90), linetype = "dotted") +
          scale_x_continuous(x.lab, breaks = seq(-10, -4, 1), 
                                    labels = my_labels) + 
          labs(title = "Graph", x = x.lab, y = y.lab)
    } else {
       geom_line(aes(x, y), data = my.data )
  }
}

Then you could use this function like:

bp <- draw.data(dat)
bp + draw.data(dat.new1, TRUE) + draw.data(dat.new2, TRUE)

This is, however, due to abscence of reproducible data untested.

0
votes

You can update your code to add each new line to an existing plot.

dat1 <- list(x = 1:10, y = c(100, 100, 90, 70, 45, 35, 30, 25, 20, 20))
dat2 <- list(x = 2:11, y = c(100, 98, 91, 73, 46, 37, 35, 30, 29, 28))

library(ggplot2)

draw.data <- function(xy, obj = ggplot()){
    # Bibliothek für ggplot-Funktion
    # Dependencies: > library("ggplot2") must be imported!

    x.lab <- "concentration [M]"
    y.lab <- "normalised luminescence [%]"

    my.data <- data.frame(xy)

    my_labels <- parse(text = paste("1E", seq(-10, -4, 1), sep = ""))

    # Find max, min and difference
    # y.max <- max(my.data$y)
    # y.min <- min(my.data$y)

    y.max <- 1
    y.min <- 0

    diff <- y.max - y.min

    # Find percentage and apply to new column 
    my.data$y <- apply(my.data, 1, function(z) ((z["y"] - y.min)/diff)*100)

    ggp.temp <- obj +
    geom_line(data = my.data, aes(x = x, y = y)) +
    # Draw 2 lines at 50% and 90% through the y-axis
    geom_hline(yintercept = c(50, 90), linetype = "dotted") + 
    scale_x_continuous(x.lab, breaks = seq(-10, -4, 1), 
        labels = my_labels) + 
    labs(title = "Graph", x = x.lab, y = y.lab)

    return (ggp.temp)
}

p1 <- draw.data(xy = dat1)
p2 <- draw.data(xy = dat2, obj = p1)
print(p2)