TL;DR Two functions in ggplot2 are overwritten (ggplot and +) to achieve code transparency and reproducibility when ggplot2 is used inside a function. It is believed that merging ggcall-like into ggplot2 can significantly enhance its functionality and accessibility, benefiting the entire R community. Powered by metaprogramming.
Overview of ggcall
ggcall
enhances ggplot2
by allowing developers to retrieve the complete code used to generate a ggplot
object. This is particularly invaluable when the original code is buried within other package internals or when dealing with multi-layered, complex plotting logic. The ability to access and understand the underlying ggplot2
code not only aids in debugging and learning but also ensures that visualizations are transparent and reproducible across various use cases.
Practical Usage
Here’s how simple it is to start with ggcall
:
library(ggcall)
# Example usage within your R package
<- your_function_that_creates_ggplot()
gg_plot <- ggcall(gg_plot)
plot_code plot_code
This functionality makes it a breeze for anyone developing or debugging complex visualizations within their packages.
Examples
Example with a dummy function with ggplot2 code
::install_github("https://github.com/Polkas/ggcall")
remoteslibrary(ggcall)
# Example: Create a function which combines a few ggplot layers
# Typically, it will be a function from your R package where you implemented ggcall
<- function(data, x, y, bool = TRUE) {
func # layers have to be added with +
<- ggplot(data, aes(x=!!as.name(x), y=!!as.name(y))) +
gg geom_point(alpha = 0.4) +
facet_grid(~gear)
if (bool) {
<- gg + theme(axis.title.x = element_blank())
gg
}
<- function(gg) {
func_internal + labs(x = "custom xlab")
gg
}
func_internal(gg)
}
# Retrieve the plot construction code
<- func(mtcars, "wt", "mpg")
gg_plot <- ggcall(gg_plot)
plot_call
plot_call# Optionally: Style the code with styler
::style_text(backports:::deparse1(plot_call))
styler
# Optional
# Access call environment and/or use it to evaluate the call
<- ggcall_env(plot_call)
plot_call_env as.list(plot_call_env)
# Reproduce the plot by evaluating the code
eval_ggcall(plot_call)
# Optionally overwrite variables
eval_ggcall(plot_call, mtcars = mtcars[1:10, ], x = "gear")
Example implementation in GGally package
ggcall
was successfully integrated into popular R packages like GGally
. Please take into account that GGally
had already overwritten the + ggplot2
function. Thus, the overwriting practice seems to be popular.
These implementations demonstrate ggcall
’s versatility and its capability to enhance the functionality of existing packages.
check out the inst/ggally.R in the ggcall repository for more details
::install_github("https://github.com/Polkas/ggally")
remoteslibrary(GGally)
data(mtcars)
# only ggmatrix related functions are not supported
<- ggcorr(mtcars, method = "everything", label = TRUE)
gg <- ggcall(gg)
gg_code ::style_text(backports:::deparse1(gg_code))
styler# Optional
# Reproduce the plot by evaluating the code
eval_ggcall(gg_code)
Why ggcall matters
For developers who build R packages that include functions generating ggplot2
plots, maintaining clarity over how each plot is constructed can be challenging. ggcall
addresses this by enabling: - Code Tracking: Extends the +
operator and the ggplot
function to maintain a history of plot construction. - Accessible History: Users can effortlessly access a sequence of ggplot2
calls used to build plots, enhancing understanding and teaching opportunities. - Reproducibility: Facilitates the easy replication and modification of plots, which is essential for testing and extending visualizations.
Implementation Insights
Please check out README file for more information.
Join the ggcall Community
Visit the GitHub repository to download ggcall
, view detailed documentation, and start making your ggplot2 visualizations more transparent and reproducible today!
Your feedback and contributions are highly appreciated as they help to refine ggcall
to better serve the R community.