daattali / ggExtra

📊 Add marginal histograms to ggplot2, and more ggplot2 enhancements
http://daattali.com/shiny/ggExtra-ggMarginal-demo/
Other
383 stars 45 forks source link

any possibility of not changing class of plots #129

Closed IndrajeetPatil closed 6 years ago

IndrajeetPatil commented 6 years ago

I have a wrapper function around ggExtra::ggMarginal (ggstatsplot::ggscatterstats: https://indrajeetpatil.github.io/ggstatsplot/articles/ggscatterstats.html) in my R package. All the other functions in this package output objects of type ggplot, which is really convenient. Because although, as a developer, have chosen some defaults, people don't lose any flexibility afforded by ggplot2 as they can always use ggplot2 commands to modify the default plot as they like. But ggscatterstats is the only function where the users can't do this and it really bugs me.


# for reproducibility
set.seed(123)

# creating dataframe
df1 <- data.frame(x = rnorm(500, 50, 10), y = runif(500, 0, 50))

# without marginals
p1 <-
    ggstatsplot::ggscatterstats(
      data = df1,
      x = x,
      y = y,
      marginal = FALSE
    )

# plot
plot(p1)


# checking class
class(p1)
#> [1] "gg"     "ggplot"

# with marginals
p2 <-
    ggstatsplot::ggscatterstats(
      data = df1,
      x = x,
      y = y,
      marginal = TRUE
    )
#> Warning: This function doesn't return a `ggplot2` object and is not further modifiable with `ggplot2` functions.
#> 

# plot
plot(p2)


# checking class
class(p2)
#> [1] "ggExtraPlot" "gtable"      "gTree"       "grob"        "gDesc"

So I am wondering if it would be possible to modify the ggMarginal function someway which makes it possible to retrieve the plot object before its class is changed? Or there is no way around this apart from me writing a separate function that can plot marginals?

https://github.com/daattali/ggExtra/blob/76d1618e75e33f72d49f37c6e875a758d7a920bb/R/ggMarginal.R#L182-L183

crew102 commented 6 years ago

The short answer is no, what you're asking for isn't possible. The class of the final object ("ggExtraPlot") is actually not the problem here, it's the object itself (the object is a gtable, not a ggplot object):

library(ggplot2)
library(gtable)
library(grid)

p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
pg <- ggplotGrob(p)

# ggMarginal basically returns one of these (a gtable):
ggextra_plot <- gtable_add_grob(x = pg, grobs = pg, t = 3, l = 4)
grid.draw(ggextra_plot)


# ...which can't be modified with ggplot functions b/c it's no longer a ggplot
# object. 
ggextra_plot + scale_x_continuous()
#> NULL

Created on 2018-08-20 by the reprex package (v0.2.0).