-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
(cc @clauswilke #3818 (comment))
Context
Let's say foo is a class defined by a package other than ggplot2 (Ex: patchwork or GGally). foo objects also inherit from gg. bar objects do not inherit from gg
You can currently perform gg_obj + foo_obj as both objects inherit from gg and would produce the same +.gg method from Opt's double dispatch.
Currently, to control how the right-hand-side (foo objects) are added, we can define ggplot_add.foo.
Problem
However, currently we can not customize how left-hand-side objects (ex: foo_obj + gg_obj) are added to gg objects.
Ex: left hand side structures are not ggplot2 objects and will not work with ggplot2 internal methods
x <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
foo_obj <- structure(
list(x, x),
class = c("foo", "gg")
)
# can not customize how the theme is added
foo_obj + theme_bw()Ex: conflicting + methods make addition impossible
x <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
bar_obj <- structure(
list(x, x),
class = c("bar") # does not inherit from 'gg'
)
`+.bar` <- function(e1, e2) {
# only add to second plot
e1[[2]] <- e1[[2]] + e2
e1
}
# Conflicting `+` methods
bar_obj + theme_bw()
#> Error in bar_obj + theme_bw() : non-numeric argument to binary operator
#> In addition: Warning message:
#> Incompatible methods ("+.bar", "+.gg") for "+" Real life situation
-
To get around this in
GGally, I overwrite the+.ggmethod. Unfortunately, this produces a warning and does not dispatch to the next available plus method.
I am open to other options, but I don't know how to produce one that would play well with other packages. -
I would like to be able to add a scale to a
ggmatrixobject in appropriate places only (Ex:ggmatrix_obj + gg_scale_obj). With the current methods, I don't know how I can do this cleanly.
Goal
Define a generic add method (ex: add_gg(e1, e2)). This generic add method should be called within +.gg to avoid double dispatch confusion involving +.
ggplot2's +.gg is not commutative. So I believe this situation has merit.
Using the implementation in #3818 , I would be able to define how a theme object is added to a custom object.
library(ggplot2)
x <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
foo_obj <- structure(
list(x, x),
class = c("foo", "gg")
)
`add_gg.foo` <- function(e1, e2) {
# only add to second plot
e1[[2]] <- e1[[2]] + e2
e1
}
print.foo <- function(x, ...) {
gridExtra::grid.arrange(x[[1]], x[[2]], ncol = 2)
}
foo_obj + theme_bw()Created on 2020-02-11 by the reprex package (v0.3.0)
