Add Multiple Curves/Functions to One Ggplot Through Looping

Add multiple curves / functions to one ggplot through looping

The issue is that all the stat_functions you are refer to the same i variable. And as a consequence, each function you add will overlay perfectly with the others.

The solution is to reassign the variable in a local scope, to make a local copy for each iteration:

p1 = ggplot(data.frame(x = 1 : 200)) + aes(x)

for (i in 1:10){
p1 = local({
j = i
p1 + stat_function(fun = function(x) x + j * 3, col = j)
})
}

To make matters more confusing, you don’t actually have to give the local variable a new name; you could just as easily have written i = i, and continued to use i. The reason is that this assignment will generate a new local variable i that masks the non-local variable i. I hope we can agree that writing such code is confusing, and a bad idea.

I’ve also taken the liberty of simplifying your code slightly by moving the data x out of the stat_function, and into the ggplot object directly.

However, it is altogether cleaner not to use a loop and reassignment here. Instead you can use lapply or map (from the purrr package):

p1 = ggplot(data.frame(x = 1 : 200)) +
aes(x) +
map(
1 : 10,
~ stat_function(fun = function (x) x + .x * 3, color = .x)
)

This is shorter, more readable (it focuses on the “what” rather than the “how”, i.e. the mechanics of the loop), and it uses a single assignment.

Using for loop to create multiple graphs with ggplot in R

This makes a plot for each "Criteria"

library(tidyverse)

sample_df <- data.frame(
stringsAsFactors = FALSE,
check.names = FALSE,
Criteria = c("A", "B", "C", "D", "E", "F"),
`Person A` = c(10L, 50L, 10L, 15L, 40L, 12L),
`Person B` = c(15L, 55L, 2L, 18L, 25L, 35L),
`Person C` = c(12L, 40L, 5L, 22L, 18L, 10L),
`Person D` = c(11L, 37L, 3L, 30L, 32L, 12L)
)

sample_df %>%
pivot_longer(cols = -Criteria,
names_to = "person",
names_prefix = "Person\\s",
values_to = "n") %>%
group_nest(Criteria) %>%
mutate(plot = map(data, ~ggplot(.x, aes(x = person, y = n)) + geom_col())) %>%
pull(plot)
#> [[1]]

Sample Image

#> 
#> [[2]]

Sample Image

#> 
#> [[3]]

Sample Image

#> 
#> [[4]]

Sample Image

#> 
#> [[5]]

Sample Image

#> 
#> [[6]]

Sample Image

Created on 2022-02-11 by the reprex package (v2.0.1)

How to generate multiple ggplots using a for loop

Try with this:

library(ggplot2)
#Function does not return graph
for (i in list){
var <- sym(i)
print(ggplot(data = test_df, aes(x= DateTime.lub, y = !!var))+
geom_line(aes(colour = Step))+
ggtitle(paste0('plot_',i)))
}

ggplot2: output multiple plots by looping

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]]

Sample Image

#> 
#> [[2]]

Sample Image

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)

Sample Image

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

Sample Image

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

Plotting multiple plots on the same page using ggplot and for loop

i in the for loop is the dataset hence res_plot_list[[i]] fails. Try -

for (i in seq_along(plots_list)) {
res_plot_list[[i]] <- residual_plots(plots_list[[i]])
}

Or why not just use lapply -

res_plot_list <- lapply(plots_list, residual_plots)

How to create several plots with different names at once (ggplot in a loop)

You can save the plots in a list. Here is a for loop to do that.

library(ggplot2)

variable_to_be_plotted<-c("a","b","c")
list_plots <- vector('list', length(variable_to_be_plotted))

for (i in seq_along(list_plots)) {
list_plots[[i]] <- ggplot(data = mydata,
aes(.data[[variable_to_be_plotted[i]]])) + geom_boxplot()
}

Individual plots can be accessed via list_plots[[1]], list_plots[[2]] etc.

how to add layers in ggplot using a for-loop

One approach would be to reshape your data frame from wide format to long format using function melt() from library reshape2. In new data frame you will have x1 values, variable that determine from which column data came, and value that contains all original y values.

Now you can plot all data with one ggplot() and geom_line() call and use variable to have for example separate color for each line.

 library(reshape2)
df.long<-melt(df,id.vars="x1")
head(df.long)
x1 variable value
1 1 y1 2.0
2 2 y1 5.4
3 3 y1 7.1
4 4 y1 4.6
5 5 y1 5.0
6 1 y2 0.4
ggplot(df.long,aes(x1,value,color=variable))+geom_line()

Sample Image

If you really want to use for() loop (not the best way) then you should use names(df)[-1] instead of seq(). This will make vector of column names (except first column). Then inside geom_line() use aes_string(y=i) to select column by their name.

plotAllLayers<-function(df){
p<-ggplot(data=df,aes(df[,1]))
for(i in names(df)[-1]){
p<-p+geom_line(aes_string(y=i))
}
return(p)
}

plotAllLayers(df)

Sample Image

Can I plot multiple function curves in a single plot using ggplot() in a user-defined function?

1) Add an i argument to the function and specify it in args= like this:

library(ggplot2)
plot_func1 <- function(i) {
p <- ggplot() + xlim(0,i) + xlab("x")
for (i in 1:i) {
p <- p +
geom_function(fun = function(x, i) i*x, args = list(i = i))
}
print(p)
}
plot_func1(4)

2) or use bquote:

library(ggplot2)
plot_func2 <- function(i) {
p <- ggplot() + xlim(0,i) + xlab("x")
for (i in 1:i) {
p <- p + geom_function(fun = bquote(function(x) .(i)*x))
}
print(p)
}
plot_func2(4)

3) or substitute i into the function like this:

library(ggplot2)
plot_func3 <- function(i) {
p <- ggplot() + xlim(0,i) + xlab("x")
for (i in 1:i) {
p <- p + geom_function(fun = substitute(function(x) i*x, list(i = i)))
}
print(p)
}
plot_func3(4)

4) or define the function as a character string with i substituted in and then parse it and convert it to a call object using [[1]]:

library(ggplot2)
plot_func4 <- function(i) {
p <- ggplot() + xlim(0,i) + xlab("x")
for (i in 1:i) {
p <- p +
geom_function(fun = parse(text = sprintf("function(x) %d*x", i))[[1]])
}
print(p)
}
plot_func4(4)


Related Topics



Leave a reply



Submit