0
votes

I want to build a ggplot graph for a given data.frame with one x-axis and multiple y.curves. Also, I want to do it within a customized function so i could call this function anytime I want to plot something with various dataframes.

The script I'm trying to develop is:

graph.date <- function(data, y.axis1, y.axis2, y.axis3, y.axis4, y.axis5, y.axis6, y.axis7, x.axis, y.lab, title, ...){
                ggplot(data, aes_string(x = x.axis)) +
                ylab(label = y.lab) + xlab(label = "Date") +
                ggtitle(label = title) +
                scale_x_date(breaks = "1 month", labels = date_format("%d-%b-%Y")) +
                geom_line(aes(y = y.axis1, colour = y.axis1), size = 1) +
                geom_line(aes(y = y.axis2, colour = y.axis2), size = 1) +
                geom_line(aes(y = y.axis3, colour = y.axis3), size = 1) +
                geom_line(aes(y = y.axis4, colour = y.axis4), size = 1) +
                geom_line(aes(y = y.axis5, colour = y.axis5), size = 1) +
                geom_line(aes(y = y.axis6, colour = y.axis6), size = 1) +
                geom_line(aes(y = y.axis7, colour = y.axis7), size = 1) +
                scale_fill_discrete() + scale_color_manual(values = c(brewer.pal(9, "Set1"), brewer.pal(9, "Set1"))) +
                labs(colour = "") + theme(plot.title = element_text(size = rel(1.76))) +
                guides(colour = guide_legend(override.aes = list(size=3))) +
                theme(text = element_text(size=20), axis.title=element_text(size=34,face="bold"), axis.text.x = element_text(face="bold",
                      color="black", size=24, angle=25), axis.text.y = element_text(face="bold", color="black", size=24, angle=0))
                } 

Then I am calling the function:

graph.date(data = BelgiumMerged, y.axis1 = "Gen1", y.axis2 = "Gen2", y.axis3 = "Gen3",
           x.axis = "Date", y.lab = "Capacity", title = "title")

The error I get is :

Error in eval(expr, envir, enclos) : object 'y.axis1' not found

2

2 Answers

0
votes

The error you get is that df does not have a column called y.axis1. The easiest way to refer to the column that have the name that is stored in the variable y.axis1 is to use aes_string() instead of aes(). Also don't set the color in the call to aes()

So change all

   geom_line(aes(y = y.axis1, colour = y.axis1), size = 1)

to

   geom_line(aes_string(y = y.axis1), size = 1,color="red") # Or whatever color you want 

However a better way to solve the problem is to reshape the dataframe to long formating so that all x coordinates lays in one column all y coordinates in one column and the grouping of these in a third column. Your function could then be defined as

graph.date <- function(df,y.axes,x.axis){
    index <- which(names(df) %in% y.axes)
    plotDF <- gather(df,y.type,y.data,index)

    ggplot(plotDF,aes_string(x.axis)) + 
    geom_line(mapping=aes(y=y.data,color=y.type))
}

Here you will pass a vector of y axes instead of having one parameter for each y axis

0
votes

Thanks a lot Nist - you're a RockStar

My final script looks as follows:

graph.date <- function(data,y.axes,x.axis, y.lab, x.lab, title){
  index <- which(names(data) %in% y.axes)
  plotDF <- gather(data,y.type,y.data,index)

  ggplot(plotDF,aes_string(x.axis)) + ggtitle(label = title) + ylab("Capacity [MW]") + xlab("Date") +
    geom_line(mapping=aes(y=y.data,color=y.type))+
    scale_fill_discrete() + scale_x_date(breaks = "1 month", labels = date_format("%d-%b-%Y")) +
    scale_color_manual(values = c(brewer.pal(9, "Set1"), brewer.pal(9, "Set1"))) + 
    labs(colour = "LegendTitle") + theme(plot.title = element_text(size = rel(1.76))) + 
    guides(colour = guide_legend(override.aes = list(size=3))) +
    theme(text = element_text(size=20), axis.title=element_text(size=34,face="bold"),
          axis.text.x = element_text(face="bold", color="black", size=24, angle=25),
          axis.text.y = element_text(face="bold", color="black", size=24, angle=0))
}

#Calling the function
graph.date(df, y.axes = c("Gen1", "Gen2", "Gen3"), x.axis = "Date", title = "title")