Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
ehthumbs.db
Thumbs.db

# test files
tests/**/*.pdf

# produced vignettes
vignettes/*.html
vignettes/*.pdf
Expand Down
7 changes: 5 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: ggstackplot
Title: Create Overlapping Stacked Plots
Version: 0.4
Version: 0.4.1
Authors@R:
c(person(
given = "Sebastian", family = "Kopf",
Expand All @@ -11,7 +11,7 @@ Authors@R:
given = "Tristan", family = "Caro",
email = "tristan.caro@colorado.edu",
role = c("aut"),
comment = c(ORCID = "")),
comment = c(ORCID = "0000-0001-6177-7444")),
person(
given = "Jamie", family = "McFarlin",
email = "jamie.mcfarlin@uwyo.edu",
Expand All @@ -27,6 +27,9 @@ Description:
Easily create overlapping grammar of graphics plots for scientific data visualization.
This style of plotting is particularly common in climatology and oceanography research communities.
License: MIT + file LICENSE
URL: https://ggstackplot.kopflab.org/,
https://github.com/kopflab/ggstackplot
BugReports: https://github.com/kopflab/ggstackplot/issues
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# ggstackplot 0.4.1

* clarify the behaviour of the `switch_axes` parameter for horizontal stackplots
* fix issue #30 to enable transformed shared axes
* update the features vignette (now called explore) with new examples
* include an example of a horizontal stackplot in the README

# ggstackplot 0.4.0

This is the first public release adding all core ggstackplot functionality.
Expand Down
33 changes: 25 additions & 8 deletions R/ggstackplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#' Stack a ggplot
#'
#' Use `ggstackplot()` to generate a stackplot. If you need more fine control, use `prepare_stackplot()` and `assemble_stackplot()` individually.
#' Use `ggstackplot()` to generate a stackplot. If you need more fine control, use `prepare_stackplot()` and `assemble_stackplot()` individually. To explore examples of all the different features, check out the `vignette("explore", "ggstackplot")` or the [online documentation](https://ggstackplot.kopflab.org/dev/articles/explore.html).
#'
#' @details
#' `ggstackplot()` stacks a ggplot template with the provided data and parameters. It returns a plot object generated by [cowplot::plot_grid()]).
Expand All @@ -15,15 +15,14 @@
#' @param palette which color to make the plots defined with an RColorBrewer palette ([RColorBrewer::display.brewer.all()]). You can only use `color` or `palette` parameter, not both.
#' @param both_axes whether to have the stacked axes on both sides (overrides alternate_axes and switch_axes)
#' @param alternate_axes whether to alternate the sides on which the stacked axes are plotted
#' @param switch_axes whether to switch the stacked axes. Not switching means the first plot in the lower left corner is always arranged like a regular ggplot with the y axis on the left and the x axis on the bottom (even if `alternate_axes = TRUE`). Setting `switch_axes = TRUE`, leads to the opposite, i.e. first plot in the lower corner has the variable axis on the other side (secondary in ggplot terms).
#' @param switch_axes whether to switch the stacked axes. Not switching means that for vertical stacks the plot at the bottom has the y-axis always on the left side; and for horizontal stacks that the plot on the left has the x-axis on top. Setting `switch_axes = TRUE`, leads to the opposite.
#' @param overlap fractional overlap between adjacent plots. The max of 1 means plots are perfectly overlaid. The min of 0 means there is no overlap. If providing multiple values, must be 1 less than the number of stacked plots (since it's describing the overlap/gap between adjacent plots). By default there is no overlap between plots
#' @param simplify_shared_axis whether to simplify the shared axis to only be on the last plot (+ first plot if a duplicate secondary axis is set)
#' @param shared_axis_size if simplify_shared_axes is true, this determines the size of the shared axis relative to the size of a single plot
#' @param template a template plot (ggplot object) to use for the stacked plots
#' @param add a list of ggplot component calls to add to specific panel plots, either by panel variable name (named list) or index (unnamed list)
#' @param debug `r lifecycle::badge("experimental")` debug flag to print the stackplot tibble and gtable intermediates
#' @examples
#'
#' # 1 step stackplot (most common use)
#' mtcars |>
#' ggstackplot(
Expand All @@ -42,6 +41,10 @@
#' ) |>
#' assemble_stackplot(overlap = c(1, 0, 0.3))
#'
#' @examplesIf interactive()
#' # many more examples available in the vignette
#' vignette("explore", "ggstackplot")
#'
#' @export
#' @returns `ggstackplot()` returns a ggplot with overlayed plot layers
ggstackplot <- function(
Expand Down Expand Up @@ -199,7 +202,7 @@ create_stackplot_tibble <- function(
.xvar = factor_in_order(names(x)),
.yvar = factor_in_order(names(y))
) |>
dplyr::arrange(dplyr::desc(.data$.xvar), .data$.yvar)
dplyr::arrange(.data$.xvar, .data$.yvar)

# do we have a valid length for color or palette?
stopifnot("can only set either `color` or `palette`, not both" = is.na(color) | is.na(palette))
Expand All @@ -223,9 +226,13 @@ create_stackplot_tibble <- function(
.axis_switch =
if (both_axes) NA else
calculate_axis_switch(
# Note: the reverse_factor and reverse = TRUE for 'vertical'
# plot are both needed to properly invert the order AND keep
# the first plot in the lower left (unless switch = TRUE)
var =
if (!!direction == "horizontal") .data$.xvar
else reverse_factor(.data$.yvar),
if (!!direction == "vertical")
reverse_factor(.data$.yvar)
else .data$.xvar,
alternate = {{ alternate_axes }},
switch = {{ switch_axes }},
reverse = !!direction == "vertical"
Expand Down Expand Up @@ -313,11 +320,21 @@ create_stackplot_gtables <- function(prepared_stackplot, overlap, simplify_share
call = call)
}

# combine plots and themes and assembel the gtables
# combine plots and themes and assemble the gtables
gtables <- prepared_stackplot |>
combine_plot_theme_add(simplify_shared_axis = simplify_shared_axis, include_adds = TRUE) |>
tidyr::unnest("config") |>
dplyr::select(".var", ".direction", "plot_w_theme") |>
dplyr::select(".var", ".direction", "plot_w_theme")

# make sure horizontal panels are in the correct order
# (reverse since horizontal positioning is inverted relative to vertical
# given the combined plot coordinate system starts in lower left corner)
if(gtables$.direction[1] == "horizontal") {
gtables <- gtables |> dplyr::arrange(dplyr::desc(dplyr::row_number()))
overlap <- rev(overlap)
}

gtables <- gtables |>
# could think about relative sizing here with size_adjust but that doesn't seem like a feature we need
dplyr::mutate(
size = 1,
Expand Down
22 changes: 14 additions & 8 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ make_color_axis_theme <- function(config) {
theme_modify_axes(
axis = if (config$.direction == "horizontal") "x" else "y",
change_color = if (!is.na(config$.color)) config$.color else NULL,
remove_primary = !is.na(config$.axis_switch) && config$.axis_switch,
remove_secondary = !is.na(config$.axis_switch) && !config$.axis_switch
remove_primary = !is.na(config$.axis_switch) &&
((config$.direction == "horizontal" && !config$.axis_switch) ||
(config$.direction == "vertical" && config$.axis_switch)),
remove_secondary = !is.na(config$.axis_switch) &&
((config$.direction == "horizontal" && config$.axis_switch) ||
(config$.direction == "vertical" && !config$.axis_switch))
) +
# make the shared axis uniform
theme_modify_axes(
Expand Down Expand Up @@ -139,7 +143,8 @@ make_plot <- function(config, data, template) {
}
if (config$.direction == "vertical" && is.null(plot$scales$scales[[x_scale_idx]]$limits)) {
# add limits
plot$scales$scales[[x_scale_idx]]$limits <- limits
plot$scales$scales[[x_scale_idx]]$limits <-
sort(plot$scales$scales[[x_scale_idx]]$transform(limits))
}
}

Expand Down Expand Up @@ -171,7 +176,8 @@ make_plot <- function(config, data, template) {
}
if (config$.direction == "horizontal" && is.null(plot$scales$scales[[y_scale_idx]]$limits)) {
# add limits
plot$scales$scales[[y_scale_idx]]$limits <- c(config$.shared_axis_min, config$.shared_axis_max)
plot$scales$scales[[y_scale_idx]]$limits <-
sort(plot$scales$scales[[y_scale_idx]]$transform(limits))
}
}

Expand Down Expand Up @@ -411,12 +417,12 @@ calculate_axis_switch <- function(var, alternate, switch, reverse) {
if (!alternate) {
# no alternating axis
return(rep(switch, length(var)))
} else if (!switch) {
# alternating axis not switched
return(var %% 2L == 0L)
} else {
} else if (switch) {
# switched alternating axis
return(var %% 2L == 1L)
} else {
# alternating axis not switched
return(var %% 2L == 0L)
}
}

77 changes: 71 additions & 6 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,79 @@ dataset$data |>
)
```

## Show me more
## What about horizontal stacks?

```{r economics, fig.height=6, message = FALSE}
```{r, message = FALSE}
# download some more data from PANGAEA
dataset2 <- pangaear::pg_data(doi = "10.1594/PANGAEA.933277")[[1]]

# show what some of these data look like
dataset2$data[
c("Depth sed [m]", "Comp", "δ13C [‰ PDB] (mean, vs. VPDB)")] |>
head() |> knitr::kable()
```

Full citation:

> `r dataset2$citation`

```{r "geodata-horizontal", message = FALSE}
library(dplyr)
library(ggplot2)
# provide a different base plot with shared graphics elements among all plots
my_template <-
# it's a ggplot
ggplot() +
# use a path plot for all (to connect the data points by depth!)
geom_point() + geom_path() +
# we still want the default stackplot theme
theme_stackplot() +
# depth is commonly plotted in reverse
scale_y_reverse()

# now make the horizontal stack through depth for 2 of the variables
dataset2$data |>
filter(Comp == "C19") |>
arrange(`Depth sed [m]`) |>
ggstackplot(
x = c(
"δ13C carb [‰ PDB]",
"n-C19 δ13C_org [‰]" = "δ13C [‰ PDB] (mean, vs. VPDB)"
),
y = "Depth sed [m]",
palette = "Dark2",
overlap = 1,
template = my_template
)
```

```{r "geodata-horizontal-2", message = FALSE}
# or show them side by side (note that this could also be achieved with
# ggplot facets except for the fine-control and coloring of the different x-axes)
dataset2$data |>
filter(Comp == "C19") |>
arrange(`Depth sed [m]`) |>
ggstackplot(
x = c(
"δ13C carb [‰ PDB]",
"n-C19 δ13C_org [‰]" = "δ13C [‰ PDB] (mean, vs. VPDB)"
),
y = "Depth sed [m]",
palette = "Dark2",
# no more overlap
overlap = 0,
# fine-tune the axes to be on top and bottom
both_axes = TRUE,
template = my_template
)
```

# using the built-in economics dataset in ggplot2 to create a horizontal stack
# instead of vertical and using many of the customization features available
# with ggstackplot and ggplot2
## Show me more

```{r economics, fig.height=6, message = FALSE}
# using the built-in economics dataset in ggplot2 to create a vertical stacke of
# double axis plots using many of the customization features available with
# ggstackplot and ggplot2
ggplot2::economics |>
ggstackplot(
# define shared x axis
Expand Down Expand Up @@ -180,4 +245,4 @@ ggplot2::economics |>

## What else can I do with ggstackplot?

- check out the **[Features](https://ggstackplot.kopflab.org/articles/features.html)** vignette for full details on all available functionality
- check out our **[Vignette](https://ggstackplot.kopflab.org/articles/explore.html)** to explore the package further with detailed examples for all the different features
Loading
Loading