ggghost

:ghost: Capture the spirit of your ggplot call

https://github.com/jonocarroll/ggghost

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (15.2%) to scientific vocabulary

Keywords

ggplot2 plotting rstats visualisation visualization
Last synced: 6 months ago · JSON representation

Repository

:ghost: Capture the spirit of your ggplot call

Basic Info
  • Host: GitHub
  • Owner: jonocarroll
  • Language: R
  • Default Branch: master
  • Homepage:
  • Size: 3.51 MB
Statistics
  • Stars: 52
  • Watchers: 3
  • Forks: 1
  • Open Issues: 2
  • Releases: 3
Topics
ggplot2 plotting rstats visualisation visualization
Created over 9 years ago · Last pushed 8 months ago
Metadata Files
Readme Changelog

README.Rmd

---
output: github_document
editor_options: 
  chunk_output_type: console
---


[![R-CMD-check](https://github.com/jonocarroll/ggghost/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/jonocarroll/ggghost/actions/workflows/R-CMD-check.yaml)




```{r, echo = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  message = FALSE,
  warning = FALSE,
  comment = "#>",
  fig.path = "README_supp/README-"
)
```

# :ghost:  _Oh, no! I think I saw a ... g-g-ghost_

![](https://github.com/jonocarroll/ggghost/raw/master/README_supp/scooby.gif)

Capture the spirit of your `ggplot2` calls.

## Motivation

`ggplot2::ggplot()` stores the information needed to build the graph as a `grob`, but that's what the **computer** needs to know about in order to build the graph. As humans, we're more interested in what commands were issued in order to build the graph. For good reproducibility, the calls need to be applied to the relevant data. While this is somewhat available by deconstructing the `grob`, it's not the simplest approach. 

Here is one option that solves that problem.

`ggghost` stores the data used in a `ggplot()` call, and collects `ggplot2` commands (usually separated by `+`) as they are applied, in effect lazily collecting the calls. Once the object is requested, the `print` method combines the individual calls back into the total plotting command and executes it. This is where the call would usually be discarded. Instead, a "ghost" of the commands lingers in the object for further investigation, subsetting, adding to, or subtracting from.

## Installation

You can install `ggghost` from CRAN with:

```{r, eval=FALSE}
install.packages("ggghost")
```
or the development version from github with:

```{r, eval=FALSE}
# install.packages("devtools")
devtools::install_github("jonocarroll/ggghost")
```

## Usage

use `%g<%` to initiate storage of the `ggplot2` calls then add to the call with each logical call on a new line (@hrbrmstr style)

```{r}
tmpdata <- data.frame(x = 1:100, y = rnorm(100))
head(tmpdata)
```

```{r, results='hide'}
library(ggplot2)
library(ggghost)
z %g<% ggplot(tmpdata, aes(x, y))
z <- z + geom_point(col = "steelblue")
z <- z + theme_bw()
z <- z + labs(title = "My cool ggplot")
z <- z + labs(x = "x axis", y = "y axis")
z <- z + geom_smooth()
```

This invisibly stores the `ggplot2` calls in a list which can be reviewed either with the list of calls
```{r}
summary(z)
```

or the concatenated call
```{r}
summary(z, combine = TRUE)
```

The plot can be generated using a `print` method
```{r}
z
```

which re-evaluates the list of calls and applies them to the saved data, meaning that the plot remains reproducible even if the data source is changed/destroyed.

The call list can be subset, removing parts of the call
```{r}
subset(z, c(1,2,6))
```

Plot features can be removed by name, a task that would otherwise have involved re-generating the entire plot
```{r}
z2 <- z + geom_line(col = "coral")
z2 - geom_point()
```

Calls are removed based on matching to the regex `\\(.*$` (from the first
bracket to the end of the call), so arguments are irrelevant. The possible
matches can be found with `summary(z)` as above


The object still generates all the `grob` info, it's just stored as calls rather than a completed image.
```{r, fig.show='hide'}
str(print(z))
#> [... truncated ...]
```

Since the `grob` info is still produced, normal `ggplot2` operators can be applied *after* the `print` statement, such as replacing the data
```{r}
xvals <- seq(0,2*pi,0.1)
tmpdata_new <- data.frame(x = xvals, y = sin(xvals))
print(z - geom_smooth()) %+% tmpdata_new
```

`ggplot2` calls still work as normal if you want to avoid storing the calls.
```{r}
ggplot(tmpdata) + geom_point(aes(x,y), col = "red")
```

Since the object is a list, we can stepwise show the process of building up the plot as a (re-)animation
```{r, eval = FALSE}
lazarus(z, "mycoolplot.gif")
```

```{r, echo = FALSE}
knitr::include_graphics("README_supp/mycoolplot.gif")
```

A supplementary data object (e.g. for use in a `geom_*` or `scale_*` call) can be added to the `ggghost` object
```{r}
myColors <- c("alpha" = "red", "beta" = "blue", "gamma" = "green")
supp_data(z) <- myColors
```

These will be recovered along with the primary data.

For full reproducibility, the entire structure can be saved to an object for re-loading at a later point. This may not have made much sense for a `ggplot2` object, but now both the original data and the calls to generate the plot are saved. Should the environment that generated the plot be destroyed, all is not lost.
```{r}
saveRDS(z, file = "README_supp/mycoolplot.rds")
rm(z)
rm(tmpdata)
rm(myColors)
exists("z")
exists("tmpdata")
exists("myColors")
```

Reading the `ggghost` object back to the session, both the relevant data and plot-generating calls can be re-executed. 
```{r}
z <- readRDS("README_supp/mycoolplot.rds")
str(z)

recover_data(z, supp = TRUE)
head(tmpdata)

myColors

z
```

We now have a proper reproducible graphic.

## Caveats

* The data _must_ be used as an argument in the `ggplot2` call, not piped in to it. Pipelines such as `z %g<% tmpdata %>% ggplot()` won't work... yet.
* ~~Only one original data set will be stored; the one in the original `ggplot(data = x)` call. If you require supplementary data for some `geom` then you need manage storage/consistency of that.~~ (fixed)
* ~~For removing `labs` calls, an argument _must_ be present. It doesn't need to be the actual one (all will be removed) but it must evaluate in scope. `TRUE` will do fine.~~

Owner

  • Name: Jonathan Carroll
  • Login: jonocarroll
  • Kind: user
  • Location: Adelaide, South Australia
  • Company: @IrregularlyScheduledProgramming

Recovering theoretical physicist / ongoing coffee addict / continually improving data scientist. I'm interested in open-source data projects, mainly in R.

GitHub Events

Total
  • Issues event: 1
  • Watch event: 1
  • Issue comment event: 4
  • Push event: 9
Last Year
  • Issues event: 1
  • Watch event: 1
  • Issue comment event: 4
  • Push event: 9

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 51
  • Total Committers: 1
  • Avg Commits per committer: 51.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 6
  • Committers: 1
  • Avg Commits per committer: 6.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Jonathan Carroll j****o@j****u 51
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 7 months ago

All Time
  • Total issues: 7
  • Total pull requests: 1
  • Average time to close issues: over 1 year
  • Average time to close pull requests: 8 minutes
  • Total issue authors: 2
  • Total pull request authors: 1
  • Average comments per issue: 0.71
  • Average comments per pull request: 1.0
  • Merged pull requests: 1
  • Bot issues: 1
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • jonocarroll (6)
  • todo[bot] (1)
Pull Request Authors
  • jonocarroll (1)
Top Labels
Issue Labels
enhancement (3) feature request (2) bug (1) housekeeping (1) todo :spiral_notepad: (1)
Pull Request Labels

Packages

  • Total packages: 2
  • Total downloads:
    • cran 175 last-month
  • Total dependent packages: 0
    (may contain duplicates)
  • Total dependent repositories: 0
    (may contain duplicates)
  • Total versions: 6
  • Total maintainers: 1
cran.r-project.org: ggghost

Capture the Spirit of Your 'ggplot2' Calls

  • Versions: 5
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 175 Last month
Rankings
Stargazers count: 7.2%
Forks count: 28.8%
Dependent packages count: 29.8%
Average: 32.7%
Dependent repos count: 35.5%
Downloads: 62.3%
Maintainers (1)
Last synced: 6 months ago
conda-forge.org: r-ggghost
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 34.0%
Stargazers count: 37.1%
Average: 45.8%
Dependent packages count: 51.2%
Forks count: 61.1%
Last synced: 6 months ago

Dependencies

DESCRIPTION cran
  • R >= 3.2.0 depends
  • animation * depends
  • ggplot2 * depends
  • testthat * suggests
.github/workflows/R-CMD-check.yaml actions
  • actions/checkout v4 composite
  • r-lib/actions/check-r-package v2 composite
  • r-lib/actions/setup-pandoc v2 composite
  • r-lib/actions/setup-r v2 composite
  • r-lib/actions/setup-r-dependencies v2 composite
.github/workflows/rhub.yaml actions
  • r-hub/actions/checkout v1 composite
  • r-hub/actions/platform-info v1 composite
  • r-hub/actions/run-check v1 composite
  • r-hub/actions/setup v1 composite
  • r-hub/actions/setup-deps v1 composite
  • r-hub/actions/setup-r v1 composite