easystats / see

:art: Visualisation toolbox for beautiful and publication-ready figures
https://easystats.github.io/see/
Other
890 stars 43 forks source link

how_to_plot methods? #9

Closed DominiqueMakowski closed 5 years ago

DominiqueMakowski commented 5 years ago

With the current structure, which makes the plotting function per se quite small and transparent (often consisting of just the ggplot chunk, as the bulk of the work is done in data_plot), it should be rather fairly easy to add a how_to_plot() method, that would actually show (print) the plot code. Then the user could copy this code and tweak it to his needs.

How does that sound?

pdwaggoner commented 5 years ago

This is interesting. Do you mean something simple like the following, or am I missing your idea?

how_to_plot  <- function(source = TRUE) {
    if (source == TRUE) {
# view source code without knowing the package
    getAnywhere(see::data_plot)
  } else {
# list the methods from the function
    methods::methods(see::data_plot)
  }
DominiqueMakowski commented 5 years ago

Close, for example, the actual code for plotting bayestestR's hdi is currently defined here:

https://github.com/easystats/see/blob/0fba4c48d95f5125fd6dee3f6a5c6303c3ce8e96/R/plot_bayestestR_hdi.R#L125-L140

One could do:

results <- hdi(rnorm(1000))
# and, instead of calling plot:
how_to_plot(results)

Which would return:

"""
x %>% 
data_plot() %>% 
     as.data.frame() %>% 
     ggplot(aes( 
       x = .data$x, 
       y = .data$y, 
       height = .data$height, 
       group = .data$y, 
       fill = .data$fill 
     )) + 
     ggridges::geom_ridgeline_gradient() + 
     add_plot_attributes(x)
"""

So the user can see, understand and reuse the exact code for plotting his HDI

I don't know how/if that would actually work

pdwaggoner commented 5 years ago

Got it. Run the following from top to bottom and it should work just fine. Let me know if you'd like me to start a PR to add the function, and if so where you'd like it. Or you could always do it yourself - whatever is easiest!

# function
how_to_plot  <- function(x, source = TRUE) {
  if (source == TRUE) {
    getAnywhere("plot.hdi")
  } else {
    warning("Be sure to set 'source = TRUE' to access source code.")
  }
}

# load libraries
library(devtools)
install_github("easystats/see")
library(see)
library(bayestestR)

# sample model
results <- hdi(rnorm(1000))

# see source code instead of plot
how_to_plot(results)

## OUTPUT:

## A single object matching ‘plot.hdi’ was found
## It was found in the following places
##   registered S3 method for plot from namespace see
##   namespace:see
## with value
##
## function (x, data = NULL, ...) 
## {
##     if (!"data_plot" %in% class(x)) {
##         x <- data_plot(x, data = data)
##     }
##     p <- x %>% as.data.frame() %>% ggplot(aes(x = .data$x, y = .data$y, 
##         height = .data$height, group = .data$y, fill = .data$fill)) + 
##         ggridges::geom_ridgeline_gradient() + add_plot_attributes(x)
##     p
## }
## <bytecode: 0x7fd9e13a1e58>
## <environment: namespace:see>

And testing the warning message when source = FALSE (i.e., non-default option in case the user tries to get clever):

how_to_plot(results, source = FALSE)

## OUTPUT

## Warning message:
## In how_to_plot(results, source = FALSE) :
##   Be sure to set 'source = TRUE' to access source code.
DominiqueMakowski commented 5 years ago

Thanks, that looks good! You could definitely try a PR. Few comments:

strengejacke commented 5 years ago

When PR'ing, don't forget to modify the DESCRIPTION and add yourself and role.

On topic: sounds all good, though I have no idea yet what you're talking about. Will dig into it later...

pdwaggoner commented 5 years ago

Thanks for the feedback - about to start the PR.

@DominiqueMakowski good ideas. For the moment, given my lack of familiarity with the full extent of the ecosystem, the PR will just be for ...\.hdi. Once its programmed in see, then we can easily modify and extend later. On that note, that's why I included source, to prepare for future build outs. Just a "place-holder" if you will, but as is, you're right, nothing major going on there. With that said, could you give me a list of all plots you'd want to include in this function? I could easily update the base function to search for a specific plot type dependent on the call from the user. So which plots would you like to include (e.g., .hdi, ...)? Thanks again!

strengejacke commented 5 years ago

ups... need to fix this now before submitting to CRAN.

how_to_plot(result)
## # Assuming that the input object is `x`:
## 
## x <- .remove_intercept(x, column = "y", show_intercept) data_plot(x) %>%
##   as.data.frame() %>%
##   ggplot(aes(x = x, y = y, height = height, group = y, fill = fill)) +
##   ggridges::geom_ridgeline_gradient() +
##   add_plot_attributes(x) +
##   geom_vline(aes(xintercept = 0))
strengejacke commented 5 years ago

we could (and should?) actually add tests for how_to_plot() in the future...

pdwaggoner commented 5 years ago

Not sure what the status is here but as I am still traveling (sorry for being MIA...) I couldn't get to this until a bit later. So if the submission to CRAN is possible without the tests, that would be ideal for speed. But totally your call on submission. Let me know.

strengejacke commented 5 years ago

Initial submission on May 20th, now I got a feedback that we should make more examples running, since we had some examples wrapped in \dontrun. I tried to enable as many examples as possible, but since some methods refer to future-functions, they don't work right now. I tried to explain this, hoping the best...

thanks for the review of our submission. We now tried to enwrap as many examples as possible. However, we have also implemented some generic plot()-methods that work for package-functions that are shipping with the next update from other packages. The reason for this "circular dependency" is that we have a set of packages for regression modelling that are very light-weight with almost no dependencies beyond R core packages, so the target-group for these packages are not only users, but also other package developers. Plotting capabilities are not required, but "nice to have". So we will add the 'see' package to the SUGGEST field of our other packages, because due to its plotting features, 'see' has much more dependencies.

TL;DR: some of the available plotting features is 'see' refer to new functions that will be shipped with the next updates from existing packages on CRAN (and are not yet available), so the example are not yet working (thus wrapped in \dontrun), but will work soon...

We don't assume any user confusion here right now, because we haven't implemented plot()-methods in the other package, anyway, and once 'see' is on CRAN, plot()-methods for other package-functions will then automatically work. But still, this only affects a small portion of 'see'-functions, most functions have running and working examples.

I'll submit an updated version of 'see', which has more example running, and long-running examples were modified to run in an acceptable amount of time.