Search code examples
rggplot2swirl

What determines the 'flipped_aes' occurence in ggplot2 objects?


I am currently writing swirl lessons where im trying to test if a ggplot2 object created by the user is somewhat equal (all.equal()) to an object i create in a custom AnswerTest. however the plot object which i receive from swirl api by accessing e$val often inherits an flipped_aes = FALSE attribute which i cannot create in my own plots and hence all.equal(e$val, someplot) fails allthough they look equal.

I would really appreciate some ideas how to work around it or control its occurence!

if it occurs all.equal() fails with the following message:

"Component “layers”: Component 1: Component 4: Length mismatch: comparison on first 2 components"

my current test looks like this:

calculates_same_graph <- function(expression){ #If ggplot expression must be written in curly brackets in Yaml file
   e <- get("e", parent.frame())
   eSnap <- cleanEnv(e$snapshot)
   
   val <- expression
   
   passed <- isTRUE(all.equal(val[-8], e$val[-8]))
   assign("e", e$val, envir = globalenv()) #only for diagnostics, changes 
                                           #when new answer is put in
   return(passed)
}

Solution

  • Ok, I agree that this is a bit weird, but I found out that the flipped_aes parameter only comes into existance after printing a plot. The weird bit is that is appears to be an object-modifying side-effect of printing the plot. This only makes sense if the paramter is being cached somehow.

    Suppose we have two plots that have opposite aesthetic flipping:

    library(ggplot2)
    
    # Should have flipped_aes = FALSE
    plot1 <- ggplot(iris, aes(Species, Sepal.Width)) +
      geom_col()
    
    # Should have flipped_aes = TRUE
    plot2 <- ggplot(iris, aes(Sepal.Width, Species)) +
      geom_col()
    

    We can see that these unprinted objects do not have flipped.aes in their geom parameters.

    # Before printing plot
    plot1$layers[[1]]$geom_params
    #> $width
    #> NULL
    #> 
    #> $na.rm
    #> [1] FALSE
    
    plot2$layers[[1]]$geom_params
    #> $width
    #> NULL
    #> 
    #> $na.rm
    #> [1] FALSE
    

    Now we can print these plots to a temporary file. Just printing it in the console should work too, I just can't replicate that in a reprex.

    # Printing as tempfile
    tmp <- tempfile(fileext = ".png")
    png(tmp)
    plot1
    plot2
    dev.off()
    #> png 
    #>   2
    unlink(tmp)
    

    Now after we've printed the plot, suddenly the plot objects have the flipped_aes parameter.

    # After printing plot
    plot1$layers[[1]]$geom_params
    #> $width
    #> NULL
    #> 
    #> $na.rm
    #> [1] FALSE
    #> 
    #> $flipped_aes
    #> [1] FALSE
    
    plot2$layers[[1]]$geom_params
    #> $width
    #> NULL
    #> 
    #> $na.rm
    #> [1] FALSE
    #> 
    #> $flipped_aes
    #> [1] TRUE
    

    Created on 2021-03-10 by the reprex package (v1.0.0)

    I don't know what the best way is to deal with this weirdness in your swirl test, but it appears that the printing of the plot influences that parameter.