How to test that 2 ggplots are functionally the same?

2 ggplot objects that produce the same visual output are not necessarily identical, yet it’s sometimes useful to assess their equivalence. How can we do this ?

It looks like the feature won’t be supported by ggplot2 so it’d be nice to have a community solution, and maybe a packaged function somewhere.

Please find my own take below. Feel free to improve on it or contribute a different approach.

expected :

library(ggplot2)
p1 <- ggplot(cars, aes(dist, speed)) + ggplot2::geom_point() 
p2 <- ggplot(cars, aes(dist, speed)) + geom_point() + scale_x_continuous(breaks = seq(0, 125, 25))
equivalent_ggplot(p1, p2)
#> [1] TRUE

equivalent_ggplot(p1, p2 + geom_blank())
#> [1] TRUE

  • 3

    just for the sake of learning, may I ask the motivation?

    – 

  • My use case is for the {constructive} package: github.com/cynkra/constructive . It generates code to construct any R object, including ggplots. We can mostly generate code that reproduces objects exactly but ggplot objects are tricky because they contain NSE artifacts, so ggplot2::geom_point() and geom_point() don’t create the same object for instance. In order to test that our generated code constructs functionally identical plots we need this feature.

    – 

  • I’m aware that {patchwork} somehow assesses equivalence of plot legends, e.g. in wrap_plots(), to test whether they should be merged. Possibly a peek under the hood would be informative. Surprised Thomas didn’t mention this when replying to your GitHub issue.

    – 

  • 2

    I don’t want to say that this is a fool’s errand, but there are too many ways in which two plots can be visually identical but with radically different structures. For example, you could have a PNG image of a ggplot drawn as a geom_raster that matches the original exactly; invisible layers of points; gridlines drawn as segments; facets made to look like they aren’t facets, etc. etc. I like the goal of reproducing ggplot code from a given plot and that’s definitely do-able, but I’m not sure how well defined your current quest is.

    – 

  • I almost feel like answering with counter-examples which wouldn’t work with the method of comparing unnamed / unlisted grobs, but that isn’t an answer. Great question, by the way!

    – 




Leave a Comment