0

I am trying to output multiple plots in ggplot2 by looping through the plot function.

Let's say I have a dataframe points with the coordinates for two points. I start by plotting a single point in ggplot2:

library(ggplot2)
point1 <- c(1,2)
point2 <- c(2,2)

points <-as.data.frame(rbind(point1,point2))

ggplot(data = points, mapping = aes(x = points[, 1], y = points[, 2])) +
    geom_point(aes(x = points[1,1], y = points[1,2])) +
    xlim(-3, 3) +
    ylim(-3, 3) +
      theme_bw()

Now I would like to loop over the dataframe so that I can produce two plots, save them in a list, and print them side by side.

I have tried:

library(ggplot2)
point1 <- c(1,2)
point2 <- c(2,2)

points <-as.data.frame(rbind(point1,point2))

point_plots_list <-  list()
for (i in 1:nrow(points)) {
  p <- ggplot(data = points, mapping = aes(x = points[, 1], y = points[, 2])) +
    geom_point(aes(x = points[i, 1], y = points[i, 2])) +
    xlim(-3, 3) +
    ylim(-3, 3) +
    theme_bw()
  point_plots_list[[i]] <- p
}
point_plots_list
#> [[1]]

#> 
#> [[2]]

Created on 2021-04-09 by the reprex package (v0.3.0)

Question

Why do the two plots look the same?

Emy
  • 817
  • 1
  • 8
  • 25
  • 1
    Besides the duplicate, your code has multiple typos or minor issues. Note that the `length()` of a `data.frame` refers to its column number, not rows. It works in your example but just because the data has as many rows as columns. Rather use `seq_len(nrow(data))`. You define the aesthetics twice in `ggplot()` and `geom_point()`. Within `ggplot()`, you call `point` not `points`. Within ggplot, you define both `data = ` and use the data in the aesthetics rather than just referring to the column names within `aes()`. – mnist Apr 09 '21 at 13:56
  • Thanks a lot for your input. I have fixed `length()` and the typo with `points`. I am new to ggplot so I kind of understand where you are getting with the other issues you are raising, but I am not sure about how to fix them. – Emy Apr 09 '21 at 14:10
  • 1
    Your specific problem is well elaborated in the linked question, I think. Cannot add more to the explanation there. – mnist Apr 09 '21 at 14:13
  • Thank you, I have followed the linked question. – Emy Apr 09 '21 at 14:22

1 Answers1

0

Following this answer:

library(ggplot2)
point1 <- c(1,2)
point2 <- c(2,2)

points <-as.data.frame(rbind(point1,point2))
point_plots_list <- vector('list', ncol(points))
point_plots_list <-  list()
for (i in 1:nrow(points)) {
  message(i)
  point_plots_list[[i]] <- local({
    i <- i
  p <- ggplot(data = points) +
    geom_point(aes(x = points[i, 1], y = points[i, 2])) +
    xlim(-3, 3) +
    ylim(-3, 3) +
    theme_bw()
  })
}
#> 1
#> 2
point_plots_list
#> [[1]]

#> 
#> [[2]]

Using lapply instead of a for loop and displaying plots with ggarrange or multiplot:

library(ggplot2)
library(ggpubr)
point1 <- c(1, 2)
point2 <- c(2, 2)

points <- as.data.frame(rbind(point1, point2))

plot_data <- function(data) {
  ggplot(data) +
    geom_point(aes(x = data[, 1], y = data[, 2])) +
    xlim(-3, 3) +
    ylim(-3, 3) +
    theme_bw()
}
myplots <- list()
myplots <- lapply(1:nrow(points), function(i) plot_data(points[i, ]))

ggarrange(myplots[[1]], myplots[[2]], 
          
          labels = c("A", "B"),
          ncol = 2, nrow = 1)

source("http://peterhaschke.com/Code/multiplot.R") #load multiplot function
multiplot(plotlist = myplots, cols = 2)
#> Loading required package: grid

Created on 2021-04-09 by the reprex package (v0.3.0)

Emy
  • 817
  • 1
  • 8
  • 25