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