Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot line or point plotting conditionally

Tags:

r

ggplot2

I'm using ggplot to write a bunch of plots inside a function. I want to pass another flag to the function so that I can choose while calling the function that whether to plot lines or points.

Currently I'm doing it like this:

plot2pdfHD = function(opdata, dir = 'plots'){
  #... do something ...
  plots <- list()

  for (i in seq(strikes)){
    #... do something ...
    plots[[i]] <- ggplot(sset, aes(x = TIMESTAMP, y = value, col = optype)) + 
      geom_line() + labs(x = "Time", y = 'values') + 
      #... do something ...
  }

  pdf(paste0(dir, '/', Sys.Date(), '.pdf'), width=16, height=10)
  for(i in seq(length(plots)))
    tryCatch({print(plots[[i]])}, error = function(e) NULL)
  dev.off()
}

I want to add a flag so that by setting appropriate value to the flag I can switch between geom_line() and geom_point() while calling the function.

Addition:

Can it be done without repeating the additional call part, i.e. #... do something ...? I am hoping for an answer that does that.

Also sset is a subset of the opdata.

like image 699
Frash Avatar asked Dec 08 '22 02:12

Frash


2 Answers

Maybe this is what you're looking for? I like @arvi1000's answer---nice and clear---but you can put the if statement inside a single ggplot addition expression:

type = "line"
## also try with
# type = "point"

ggplot(mtcars, aes(x = wt, y = mpg)) + {
      if(type == "point") geom_point() else geom_line()
    } +
    theme_bw()

For multiple layers, you could do something like this:

gg = ggplot(mtcars, aes(x = wt, y = mpg))

{
  if(type == "point") {
    gg + geom_point() 
  } else {
    gg + geom_line() + stat_smooth()
  }
} + theme_bw()

(Of course, adding the theme_bw() to the original gg definition would be cleaner, but this demonstrates that it can be added later.)

like image 77
Gregor Thomas Avatar answered Jan 08 '23 09:01

Gregor Thomas


Plain old if block?

plot2pdfHD = function(opdata, dir = 'plots', plot_type){

  plots <- list()

  for (i in seq(strikes)) {

    # base gg call
    p <- ggplot(sset, aes(x = TIMESTAMP, y = value, col = optype))

    # add geom layer based on content of argument:
    if(plot_type == 'line')  p <- p + geom_line()      
    if(plot_type == 'point') p <- p + geom_point()

    # add additional params and assign into list item        
    plots[[i]] <- p + labs(x = "Time", y = 'values')

    #...
  }

  # ...
}

Other notes:

  • I'm assuming you are doing something to make sset different before each call, otherwise you are going to get a list of identical plots
  • lapply might be better than a for loop here, esp since you are wanting a list object as the result anyway
like image 41
arvi1000 Avatar answered Jan 08 '23 11:01

arvi1000