Skip to content

Commit

Permalink
Fix #345 and fix #379 add new capabilities to free
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasp85 committed Sep 2, 2024
1 parent 03197c7 commit d346b93
Show file tree
Hide file tree
Showing 19 changed files with 1,295 additions and 72 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ S3method(print,patchwork)
S3method(print,plot_dimension)
S3method(set_dim,ggplot)
S3method(set_dim,patchwork)
S3method(simplify_gt,free_table)
S3method(simplify_gt,gtable)
S3method(simplify_gt,gtable_patchwork)
S3method(simplify_gt,inset_table)
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* Fix a bug where guide collecting would prevent proper axes collecting (#359)
* Fix a bug in `free()` where tags placed on top of the plot region would become
missing (#350)
* `free()` gains `type` and `side` argument. The first to control whether to
free the panel, the label, or the space occupied outside the panel, the second
to control which sides it applies to (#345 and #379)

# patchwork 1.2.0

Expand Down
6 changes: 6 additions & 0 deletions R/add_plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ get_patches <- function(plot) {
patches <- plot$patches
plot$patches <- NULL
class(plot) <- setdiff(class(plot), 'patchwork')
if (is_free_plot(plot)) {
attr(plot, "patchwork_free_settings") <- NULL
if (is.null(attr(plot, "free_settings"))) {
class(plot) <- setdiff(class(plot), 'free_plot')
}
}
} else {
patches <- new_patchwork()
}
Expand Down
47 changes: 44 additions & 3 deletions R/free.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,25 @@
#' other plots in the composition.
#'
#' @param x A ggplot or patchwork object
#' @param type Which type of freeing should be applied. See the Details section
#' @param side Which side should the freeing be applied to. A string containing
#' one or more of "t", "r", "b", and "l"
#'
#' @return A modified version of `x` with a `free_plot` class
#'
#' @details
#' `free()` has multiple modes depending on what you are needing:
#'
#' The default `"panel"` will allow the panel area to ignore alginment with the
#' remaining plots and expand as much as needed to fill any empty space.
#'
#' The `"label"` type will instead free the axis label to keep its proximity to
#' the axis, even if a longer axis text from another plot would push them apart.
#'
#' The `"space"` type also keeps axis and title together, but will instead not
#' reserve any space for it. This allows the axis to occupy space in an
#' otherwise empty area without making additional space available for itself.
#'
#' @importFrom ggplot2 is.ggplot
#' @export
#'
Expand All @@ -38,15 +54,40 @@
#'
#' p1 / p2
#'
#' # We can fix this be using free
#' # We can fix this be using free (here, with the default "panel" type)
#' free(p1) / p2
#'
#' # If we still want the panels to be aligned to the right, we can choose to
#' # free only the left side
#' free(p1, side = "l") / p2
#'
#' # We can still collect guides like before
#' free(p1) / p2 + plot_layout(guides = "collect")
#'
free <- function(x) {
#' # We could use "label" to fix the layout in a different way
#' p1 / free(p2, "label")
#'
#' # Another issue is that long labels are not using already available free
#' # space.
#' plot_spacer() + p1 + p2 + p2
#'
#' # This can be fixed with the "space" type
#' plot_spacer() + free(p1, "space", "l") + p2 + p2
#'
free <- function(x, type = c("panel", "label", "space"), side = "trbl") {
check_object(x, function(x) is.ggplot(x) || is_patchwork(x), "a <ggplot> or <patchwork> object")
class(x) <- c("free_plot", class(x))
type <- arg_match(type)
side <- tolower(side)
if (grepl("[^trbl]", side)) {
abort("{.arg side} can only contain the t, r, b, and l characters: ")
}
settings <- list(type = type, sides = side)
if (is_patchwork(x)) {
attr(x, "patchwork_free_settings") <- settings
} else {
attr(x, "free_settings") <- settings
}
class(x) <- unique(c("free_plot", class(x)))
x
}
is_free_plot <- function(x) inherits(x, "free_plot")
4 changes: 2 additions & 2 deletions R/inset_element.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ inset_element <- function(p, left, bottom, right, top, align_to = 'panel', on_to
p <- wrap_elements(full = p, clip = clip)
}
clip <- if (clip) 'on' else 'off'
attr(p, 'settings') <- list(left = left, bottom = bottom, right = right,
attr(p, 'inset_settings') <- list(left = left, bottom = bottom, right = right,
top = top, align_to = align_to, on_top = on_top,
clip = clip, ignore_tag = ignore_tag)
class(p) <- c('inset_patch', class(p))
Expand All @@ -91,4 +91,4 @@ print.inset_patch <- function(x, newpage = is.null(vp), vp = NULL, ...) {
#' @export
plot.inset_patch <- print.inset_patch
#' @export
has_tag.inset_patch <- function(x) !attr(x, 'settings')$ignore_tag
has_tag.inset_patch <- function(x) !attr(x, 'inset_settings')$ignore_tag
Loading

0 comments on commit d346b93

Please sign in to comment.