1

I'm trying to define this function to easily set a custom theme to a ggplot, but I'm having trouble using the functions like element_blank() dynamically.. For example, specifying whether or not to have vertical gridlines as a TRUE/FALSE argument:

qplot(data=df, x=quarter, y=value, geom="line") + 
  style(grid.vertical = F)


style = function (grid.vertical = T) {
(theme_foundation() + 
 theme(
       panel.grid.major.x = ifelse(grid.vertical == T, element_line(), element_blank())
 ))}

produces..

Error in (function (el, elname)  : 
Element panel.grid.major.x must be a element_line object.

Is there a way to make this work?

2 Answers 2

2

It seems that the error is produced by an unpleasant peculiarity of ifelse. I tried the workaround from the accepted answer there, but that did not help. So I guess the simplest way would be to switch to the regular if, though the code doesn't seem to be particularly neat.

style.if = function (grid.vertical = T) {
  t <- theme()
  if (grid.vertical) 
    t <- t + theme(panel.grid.major.x = element_line(colour = 'red'))
  else t <- t + theme(panel.grid.major.x = element_blank())
  t
}

ggplot(mtcars, aes(x=wt, y=mpg)) + geom_line() + style.if()
ggplot(mtcars, aes(x=wt, y=mpg)) + geom_line() + style.if(F)
Sign up to request clarification or add additional context in comments.

Comments

1

This has to do with how the ggplot code is checking for types:

...
else if (!inherits(el, eldef$class) && !inherits(el, "element_blank")) {
    stop("Element ", elname, " must be a ", eldef$class, 
        " object.")
}

Since we're using the ifelse function, I think this dynamic type checking voodoo will look at ifelse as being the "element" here, so the conditions are never met since it doesn't inherit from element_blank. To solve this, just use regular if/else expression instead of ifelse:

style = function (grid.vertical = T) {
(theme_foundation() + 
 theme(
       panel.grid.major.x = if(grid.vertical == T) element_line() else element_blank()
 ))}

I had the exact same problem and this solution worked for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.