-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.Rmd
175 lines (122 loc) · 6.76 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "50%"
)
```
# ggdatasaver
<!-- badges: start -->
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[![CRAN status](https://www.r-pkg.org/badges/version/ggdatasaver)](https://CRAN.R-project.org/package=ggdatasaver)
[![R-CMD-check](https://github.com/eliocamp/ggdatasaver/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/eliocamp/ggdatasaver/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
The goal of ggdatasaver is to automatically save the data associated with your plots for you to share as supplementary material.
Other people can then use that data instead of digitising your plots.
Because only the data already being published as a plot is saved, there should be fewer privacy or legal complications.
## Installation
You can install the development version of ggdatasaver like so:
``` r
remotes::install_github("eliocamp/ggdatasaver")
```
## Example
ggdatasaver works automatically with knitr.
The only thing you need to do is to define the directory where the data is saved with
```{r}
ggdatasaver::save_plot_data_in("plot-data")
```
Then, just create your ggplot2 figures as always.
Using a chunk label is encouraged because it will be used to name the file.
```{r mpg, fig.alt = "Scatterplot of mpg vs disp with a fitted smooth line showing a decreasing relationship."}
library(ggplot2)
ggplot(mtcars, aes(mpg, disp)) +
geom_point() +
geom_smooth()
```
After you knit, you will have a (possibly new) directory with zip files with the data of each plot.
```{r}
fs::dir_tree("plot-data")
```
Inside that zip file there will be a csv file for each layer.
```{r}
# Unzip the contents of mpg.zip into a temporary directory.
dir <- file.path(tempdir(), "mpg")
utils::unzip("plot-data/mpg-1.zip", exdir = dir)
fs::dir_tree(dir)
```
The data of each layer is only the one used to draw the geometry.
For example, GeomSmooth.csv has the coordinates of the fit and some other aesthetic information
```{r}
smooth <- read.csv(file.path(dir, "GeomSmooth.csv"))
knitr::kable(head(smooth))
```
And the line can be reconstructed exactly from these data.
```{r, plot_data_dir = NULL, fig.alt = "The same figure from before but only the smooth fit."}
ggplot(smooth, aes(x, y)) +
geom_ribbon(aes(ymin = ymin, ymax = ymax, fill = I(fill), alpha = I(alpha))) +
geom_line(aes(colour = I(colour), size = I(size)))
```
(Setting `plot_data_dir` to `NULL` will suppress data-saving for that chunk.)
As you can see, only the coordinates of each geom are saved, not the underlying data.
For a more dramatic example, take this controur plot of the Old Faithful Geyser Data.
```{r faithful-density, fig.alt = "2D density contours of eruptions vs. waiting shoing two distinct areas of high density, one centered at ~4.5 eruptions and ~80 waiting and one at 2 eruptions and 55 waiting."}
ggplot(faithful, aes(x = eruptions, y = waiting)) +
geom_density_2d()
```
(Now there are two zip files in the `plot-data` directory
```{r}
fs::dir_tree("plot-data")
```
.)
ggdatasaver will save the coordinates that defined the contours, not the observations from which they were computed.
```{r, plot_data_dir = NULL, fig.alt = "The same plot from before."}
dir <- file.path(tempdir(), "faithful-density")
utils::unzip("plot-data/faithful-density-1.zip", exdir = dir)
density <- read.csv(file.path(dir, "GeomDensity2d.csv"))
ggplot(density, aes(x, y)) +
geom_path(aes(group = group))
```
This makes it safe to share these data, as it doesn't include any more information than what's in the plot you are already sharing.
The panel specification of each plot is saved in layout.csv, which holds the location (ROW and COLumn) information of each panel as well as the value of the variables
```{r mpg-facets, fig.alt = "Scatterplot of displ vs cty with 12 panels organised in 2 rows and 4 columns according to the values of drv and cyl."}
ggplot(mpg, aes(displ, cty)) +
geom_point() +
facet_grid(drv ~ cyl)
```
```{r}
dir <- file.path(tempdir(), "mpg-facets")
utils::unzip("plot-data/mpg-facets-1.zip", exdir = dir)
layout <- read.csv(file.path(dir, "layout.csv"))
head(layout)
```
```{r, include = FALSE}
unlink("plot-data", recursive = TRUE)
```
## Use cases
### Accessibilty
Academic journals almost never have any infrastructure that allows for alt text for figures.
For blind people, having access to the raw data is better than nothing.
With the data they could print a tactile version (for simple plots), compute statistics to get a better sense of the relationships, or just read the raw data.
For fitted curves, which usually are not adequately described in text, they could get the data, fit the curve and read the curve parameters.
### Reproducibilty
An important aspect of reproducibility is having access to data, but this is easier said than done.
Huge data is expensive to store and serve, and many types of data carry privacy concerns (such as patient data) or licencing issues (like secret data).
Another barrier to data sharing is organising it in useful way (see [The Turing Way's Guide to Reproducible Research](https://the-turing-way.netlify.app/reproducible-research/open/open-data.html#barriers-to-data-sharing)).
While not perfect, sharing the small snippets of data that are the coordinates of plot geometries can be a good compromise.
These data are generally small and already in a tabular format, so it's technically easy to share in a repository or as supplemental material.
And because is data that is already implicitly shared as an image, it doesn't carry privacy and licencing concerns.
(I'm not a lawyer, so don't take that as legal advice.)
And even when the raw data is shared, sharing also the plot data can be useful for researchers that want to reproduce or reanalise small chunks of your results but don't want or can't download the original data and run the code.
## Limitations
ggdatasaver has only been tested on simple plots although there's no reason it should work work with more complicated ones.
[patchwork](https://patchwork.data-imaginist.com/) is supported but not [cowplot](https://wilkelab.org/cowplot/).
When using ggdatasaver plots are built twice; once when saving the data and once when drawing the plot.
This shouldn't be an issue most of the time unless your plot requires heavy computation.
Only data from ggplot2 plots are exported.
Base plots or lattice plots are not supported; only because I don't know how to go about it.
If you have any idea of how to implement ggdatasaver for base plots, open an issue and let's talk about it!