Home > Blockchain >  Create ggplot multiple graphs dynamically with loop in R
Create ggplot multiple graphs dynamically with loop in R

Time:09-14

I am trying to build multiple graphs with ggplot in batch. The graphs all come from the same dataframe, the only thing I need to change is the metric (y axis) that I observe.

What I am doing now is far from efficient as I am copy-pasting the ggplot setup for each graph and just changing the metric where it needs to be modified.

I know there is a way, to dynamically create these graphs by just listing all the metrics that need to change dynamically so that I only need to use ggplot once in a loop.

I think in the past I managed to do it using eval() , get() and maybe assign() but I can't remember how I had done it.

Ideally, in the end I would have the different graphs created with each a unique name based on the metric: Forecast_Monthly_Visits_FR_Graph, Forecast_Monthly_Sales_FR_Graph etc. Below a reproducible example. Thanks a lot.

library(ggplot2)

Date <- as.Date(c('2022-01-01','2022-01-02','2022-01-03','2022-01-01','2022-01-02','2022-01-03'))
Type <- c("Actual", "Actual", "Actual", "Forecast", "Forecast", "Forecast")
Visits <- c(67398,63398,61398,53422,72726,92822)
Sales <- c(17398,23398,41398,12422,33726,53822)
Actual_Forecast_Monthly_France <- data.frame(Date , Type , Visits, Sales)

Forecast_Monthly_Visits_FR_Graph <-
  ggplot(data=Actual_Forecast_Monthly_France, aes(x=Date, y=Visits, group=Type,  linetype = factor(Type) , show.legend = FALSE))  
  geom_line(aes(color=Type))  
  geom_point(size = 0.5)  
  geom_text(aes(label=round(Visits)), size = 3)  
  theme(axis.text.x = element_text(angle = 90))  
  labs(title = "Visits")  
  theme(plot.title = element_text(hjust = 0.5))  
  scale_color_manual(values= c("#03a623", "#030063", "#ffaad7", "#b6b6b6"))

Forecast_Monthly_Visits_FR_Graph

 Forecast_Monthly_Sales_FR_Graph <-
  ggplot(data=Actual_Forecast_Monthly_France, aes(x=Date, y=Sales, group=Type,  linetype = factor(Type) , show.legend = FALSE))  
  geom_line(aes(color=Type))  
  geom_point(size = 0.5)  
  geom_text(aes(label=round(Sales)), size = 3)  
  theme(axis.text.x = element_text(angle = 90))  
  labs(title = "Sales")  
  theme(plot.title = element_text(hjust = 0.5))  
  scale_color_manual(values= c("#03a623", "#030063", "#ffaad7", "#b6b6b6"))

Forecast_Monthly_Sales_FR_Graph 

CodePudding user response:

You can create a function which includes the y variable you want to plot. Then it becomes relatively simple to create a for loop to cycle through multiple y variable options or you could use a function from purrr. Now included the loop, and I've had to go down the route of quoted variables names as @stefan explained.

library(ggplot2)
library(purrr)

gg_fun <- function(y_var){
  Forecast_Monthly_Visits_FR_Graph <-
    ggplot(data=Actual_Forecast_Monthly_France, aes(x=Date, y=!!sym(y_var), group=Type,  linetype = factor(Type) , show.legend = FALSE))  
    geom_line(aes(color=Type))  
    geom_point(size = 0.5)  
    geom_text(aes(label=round(Visits)), size = 3)  
    theme(axis.text.x = element_text(angle = 90))  
    labs(title = y_var)  
    theme(plot.title = element_text(hjust = 0.5))  
    scale_color_manual(values= c("#03a623", "#030063", "#ffaad7", "#b6b6b6"))
  
  return(Forecast_Monthly_Visits_FR_Graph)
  
}

gg <- map(c("Visits", "Sales"), gg_fun)


gg[[1]]

gg[[2]]

Created on 2022-09-13 with reprex v2.0.2

data

Date <- as.Date(c('2022-01-01','2022-01-02','2022-01-03','2022-01-01','2022-01-02','2022-01-03')) Type <- c("Actual", "Actual", "Actual", "Forecast", "Forecast", "Forecast") Visits <- c(67398,63398,61398,53422,72726,92822) Sales <- c(17398,23398,41398,12422,33726,53822) Actual_Forecast_Monthly_France <- data.frame(Date , Type , Visits, Sales)

Created on 2022-09-13 with reprex v2.0.2

CodePudding user response:

Similar to the approach by @Peter with the exception that I pass the column names as strings which IMHO makes it a bit easier to loop over the columns using e.g. lapply. Note, as I pass the column names as strings I use the .data pronoun:

library(ggplot2)

plot_fun <- function(x) {
  ggplot(data = Actual_Forecast_Monthly_France, aes(x = Date, y = .data[[x]], group = Type, linetype = factor(Type), show.legend = FALSE))  
    geom_line(aes(color = Type))  
    geom_point(size = 0.5)  
    geom_text(aes(label = round(Visits)), size = 3)  
    theme(axis.text.x = element_text(angle = 90))  
    labs(title = x)  
    theme(plot.title = element_text(hjust = 0.5))  
    scale_color_manual(values = c("#03a623", "#030063", "#ffaad7", "#b6b6b6"))
}

cols <- names(Actual_Forecast_Monthly_France)[!names(Actual_Forecast_Monthly_France) %in% c("Date", "Type")]
names(cols) <- cols

lapply(cols, plot_fun)
#> $Visits

#> 
#> $Sales

  • Related