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
1 change: 0 additions & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@
^codecov.yml$
^doc$
^Meta$
^ggstackplot\.Rproj$
^codecov\.yml$
^\.covrignore$
20 changes: 12 additions & 8 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.3.0
Version: 0.3.9999
Authors@R:
c(person(
given = "Sebastian", family = "Kopf",
Expand Down Expand Up @@ -29,22 +29,26 @@ Description:
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.2
Depends:
R (>= 4.1.0)
Imports:
rlang,
cli,
methods,
rlang (>= 0.4.11),
lifecycle,
tidyselect,
dplyr,
tidyr,
ggplot2,
cowplot,
RColorBrewer
Suggests:
covr,
knitr,
rmarkdown,
roxygen2,
testthat,
lifecycle,
scales
testthat (>= 3.0.0),
vdiffr,
scales,
pangaear
Config/testthat/edition: 3
VignetteBuilder: knitr
14 changes: 2 additions & 12 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
# Generated by roxygen2: do not edit by hand

export(":=")
export(.data)
export(as_label)
export(as_name)
export(assemble_stackplot)
export(enquo)
export(enquos)
export(ggstackplot)
export(prepare_stackplot)
export(theme_stackplot)
import(cli)
import(ggplot2)
import(rlang)
importFrom(rlang,":=")
importFrom(rlang,.data)
importFrom(rlang,as_label)
importFrom(rlang,as_name)
importFrom(rlang,enquo)
importFrom(rlang,enquos)
importFrom(lifecycle,deprecated)
28 changes: 5 additions & 23 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
# isoorbi 1.1.0
# ggstackplot 0.4.0

This is a major release adding substantial new features and fixing a few bugs.
This is the first public release adding all core ggstackplot functionality.

## Breaking changes
## Features

There are no breaking changes in this release (all changes and new features are backwards compatible).

## New features

* implemented block annotation functionality (FIXME: explain more)
* implemented package settings (FIXME: explain more)

## Enhancements

* removed dependency on `stringr`
* implemented native pipe `|>` (R version requirement increased to 4.1.0) and removed dependency on `magrittr`
* added `.by` parameter for `orbi_summarize_results()` for option to manually adjust grouping

## Bug fixes

* `dplyr` changes to joins with explicit `multiple` argument are now implemented (#10)

# isorbi 1.0.0

First public release.
* generate horizontally and vertically stacked plots
* modify color, plot templates, and individual plot elements
15 changes: 15 additions & 0 deletions R/ggstackplot-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## usethis namespace: start
#' @import rlang
#' @import cli
#' @import ggplot2
#' @importFrom lifecycle deprecated
## usethis namespace: end
NULL

#' @aliases NULL ggstackplot-package
#' @details
#' `r lifecycle::badge("stable")`
#'
#' Have you ever wanted to create (partly) overlapping line plots with matched color-coding of the data and axes? These kinds of plots are common in climatology and oceanography research but there is not an easy way to create them with ggplot facets. The ggstackplot package builds on [ggplot2](https://ggplot2.tidyverse.org/) to provide a straightforward approach to building these kinds of plots while retaining the powerful grammar of graphics approach of ggplots. Check out the functionality provided by ggstackplots at <https://ggstackplot.kopflab.org>
#'
"_PACKAGE"
43 changes: 24 additions & 19 deletions R/ggstackplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#' @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 debug flag to print the stackplot tibble and gtable intermediates
#' @param debug `r lifecycle::badge("experimental")` debug flag to print the stackplot tibble and gtable intermediates
#' @examples
#'
#' # 1 step stackplot (most common use)
Expand Down Expand Up @@ -122,48 +122,48 @@ prepare_stackplot <- function(

# internal function to prepare the data for a ggstackplot
create_stackplot_tibble <- function(
data, x, y, remove_na = TRUE, color = NA, palette = NA, both_axes = FALSE, alternate_axes = FALSE, switch_axes = FALSE) {
data, x, y, remove_na = TRUE, color = NA, palette = NA, both_axes = FALSE, alternate_axes = FALSE, switch_axes = FALSE, call = caller_env()) {

# do we have a data frame?
if (missing(data) || !is.data.frame(data)) {
abort("`data` must be a data frame or tibble.")
cli_abort("`data` must be a data frame or tibble.", call = call)
}

# do x and y evaluate correctly?
x <- try_fetch(
tidyselect::eval_select(rlang::enexpr(x), data),
error = function(cnd) {
abort(
cli_abort(
"`x` must be a valid tidyselect expression.",
parent = cnd
parent = cnd, call = call
)
}
)
y <- try_fetch(
tidyselect::eval_select(rlang::enexpr(y), data),
error = function(cnd) {
abort(
cli_abort(
"`y` must be a valid tidyselect expression.",
parent = cnd
parent = cnd, call = call
)
}
)

# do we have at least 1 x and 1 y?
if (length(x) < 1 || length(y) < 1) {
abort(c(
cli_abort(c(
"insufficient number of columns",
"x" = if (length(x) < 1) "no `x` column selected",
"x" = if (length(y) < 1) "no `y` column selected"
))
), call = call)
}
# do we have both multiple x AND y?
if (length(x) > 1 && length(y) > 1) {
abort(c(
cli_abort(c(
"too many columns, only x OR y can select multiple columns",
"x" = if (length(x) < 1) "no `x` column selected",
"x" = if (length(y) < 1) "no `y` column selected"
))
), call = call)
}

# do we have valid remove_na, both_axes, alternate_axes, and switch_axes (the booleans)
Expand Down Expand Up @@ -204,15 +204,15 @@ create_stackplot_tibble <- function(
# 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))
if (!(is.character(color) || all(is.na(color))) || !length(color) %in% c(1L, nrow(config))) {
abort(sprintf("`color` must be either a single color or one for each variable (%d)", nrow(config)))
cli_abort(sprintf("`color` must be either a single color or one for each variable (%d)", nrow(config)), call = call)
}
if (!all(is.na(palette))) {
# palette argument provided
if (is_scalar_character(palette) && palette %in% rownames(RColorBrewer::brewer.pal.info) && RColorBrewer::brewer.pal.info[palette, 1] >= nrow(config)) {
color = RColorBrewer::brewer.pal(RColorBrewer::brewer.pal.info[palette, 1], palette)[1:nrow(config)]
} else
sprintf("`palette` must be a string identifying a valid RColorBrewer palette with at least %d colors. Use `RColorBrewer::display.brewer.all()` to see all available palettes.", nrow(config)) |>
abort()
cli_abort(call = call)
}


Expand Down Expand Up @@ -290,28 +290,33 @@ assemble_stackplot <- function(prepared_stackplot, overlap = 0, simplify_shared_
}

# internal function to great a list of gtables for the combined plot
create_stackplot_gtables <- function(prepared_stackplot, overlap, simplify_shared_axis, shared_axis_size) {
create_stackplot_gtables <- function(prepared_stackplot, overlap, simplify_shared_axis, shared_axis_size, call = caller_env()) {

# do we have a data frame?
req_cols <- c(".var", "config", "data", "plot", "theme")
if (missing(prepared_stackplot) || !is.data.frame(prepared_stackplot) ||
!all(req_cols %in% names(prepared_stackplot))) {
abort(
sprintf("`prepared_stackplot` must be a data frame or tibble with columns '%s'", paste(req_cols, collapse = "', '"))
cli_abort(
"{.var prepared_stackplot} must be a data frame or tibble with columns
{.emph {req_cols}}", call = call
)
}

# do we have a valid overlap value?
if (missing(overlap) || !is.numeric(overlap) || !all(overlap >= 0) || !all(overlap <= 1) ||
!length(overlap) %in% c(1L, nrow(prepared_stackplot) - 1L)) {
abort(sprintf("`overlap` must be either a single numeric value (between 0 and 1) or one for each sequential plot overlap (%d)",
nrow(prepared_stackplot) - 1L))
cli_abort(
c("{.var overlap} must be either a single numeric value (between 0 and 1)
or a vector with {nrow(prepared_stackplot) - 1L} numbers, one for the
overlap of each sequential plot",
"x" = "{.var overlap} is a {.obj_type_friendly {overlap}}"),
call = call)
}

# combine plots and themes and assembel the gtables
gtables <- prepared_stackplot |>
combine_plot_theme_add(simplify_shared_axis = simplify_shared_axis, include_adds = TRUE) |>
tidyr::unnest(.data$config) |>
tidyr::unnest("config") |>
dplyr::select(".var", ".direction", "plot_w_theme") |>
# could think about relative sizing here with size_adjust but that doesn't seem like a feature we need
dplyr::mutate(
Expand Down
12 changes: 6 additions & 6 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

#' Recommended base theme for stacked gg plots
#'
#' Returns a basic ggplot2 theme that extends [ggplot2::theme_bw()] with a transparent plot background to make sure overlapping plots do not cover each other up.
#'
#'
#' @return `ggplot2::theme()` object
#' @return [ggplot2::theme()] object
#' @examples
#' library(ggplot2)
#' template <- ggplot() + geom_line() + theme_stackplot()
Expand Down Expand Up @@ -208,21 +208,21 @@ process_add_ons <- function(prepared_stackplot, add) {
sprintf("no match for `add` component(s) '%s' in variables ('%s')",
paste(add_names[is.na(add_indices)], collapse = "', '"),
paste(prepared_stackplot$.var, collapse = "', '")) |>
abort()
cli_abort()
}

# check for indices outside what's possible
if (any(out_of_range <- !add_indices %in% seq_along(prepared_stackplot$.var))) {
sprintf("`add` component(s) index out of range: %s",
paste(add_indices[out_of_range], collapse = ", ")) |>
abort()
cli_abort()
}

# check for duplicates
if (any(dups <- duplicated(add_indices))) {
sprintf("multiple `add` component definitions for variable(s) '%s'",
paste(prepared_stackplot$.var[unique(add_indices[dups])], collapse = "', '" )) |>
abort()
cli_abort()
}

# store adds
Expand Down Expand Up @@ -295,7 +295,7 @@ combine_plot_theme_add <- function(prepared_stackplot, simplify_shared_axis, inc
if(!is.null(simplify_axis)) {
if (any(grepl(sprintf("scale_%s_", simplify_axis), as.character(add)))) {
sprintf("invalid add-on for '%s' plot: `%s`. Modifications of the shared %s-axis are not allowed because it can lead to deceptive visualizations. You can modify the shared axis in the template or switch to `simplify_shared_axis = FALSE`.", var, as_label(add), simplify_axis) |>
abort()
cli_abort()
}
}

Expand Down
11 changes: 4 additions & 7 deletions R/import-standalone-purrr.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Standalone file: do not edit by hand
# Source: <https://github.com/r-lib/rlang/blob/main/R/standalone-purrr.R>
# Source: https://github.com/r-lib/rlang/blob/HEAD/R/standalone-purrr.R
# Generated by: usethis::use_standalone("r-lib/rlang", "purrr")
# ----------------------------------------------------------------------
#
# ---
Expand Down Expand Up @@ -169,19 +170,15 @@ every <- function(.x, .p, ...) {
.p <- as_function(.p, env = global_env())

for (i in seq_along(.x)) {
if (!rlang::is_true(.p(.x[[i]], ...))) {
return(FALSE)
}
if (!rlang::is_true(.p(.x[[i]], ...))) return(FALSE)
}
TRUE
}
some <- function(.x, .p, ...) {
.p <- as_function(.p, env = global_env())

for (i in seq_along(.x)) {
if (rlang::is_true(.p(.x[[i]], ...))) {
return(TRUE)
}
if (rlang::is_true(.p(.x[[i]], ...))) return(TRUE)
}
FALSE
}
Expand Down
5 changes: 0 additions & 5 deletions R/package.R

This file was deleted.

Loading
Loading