13  Operators

In ggalign, operators are used to manage and manipulate plot elements within various layouts. These operators enable you to build complex visualizations by adding or modifying components across multiple plots in a layout. You are likely familiar with the addition operator (+); this section expands on its usage and introduces two additional operators: logical AND (&) and subtraction (-), explaining how to apply them in different contexts.

  1. Addition Operator (+): Adds elements to the active plot in the active layout.
  2. Logical AND Operator (&): Applies elements to all plots in the layout.
  3. Subtraction Operator (-): Allows you to add elements or modify them across multiple plots in the layout
Code
library(ggalign)
#> Loading required package: ggplot2
#> 
#> Attaching package: 'ggalign'
#> The following object is masked from 'package:ggplot2':
#> 
#>     element_polygon
set.seed(123)
small_mat <- matrix(rnorm(56), nrow = 7)
rownames(small_mat) <- paste0("row", seq_len(nrow(small_mat)))
colnames(small_mat) <- paste0("column", seq_len(ncol(small_mat)))

circle_layout() follows the same principles as stack_layout() but does not support nesting. Examples below focus on stack_layout() and quad_layout().

13.1 Addition Operator

+: adds elements to the active plot in the active layout.

The + operator is straightforward and should be used as needed.

In stack_layout(), a nested layout will only occur if you pass a quad_layout() into stack_layout() (?sec-multiple-quad-layouts). If the active context in the stack_layout() is quad_layout(), this quad_layout() is treated as the active layout, and the + operator will add elements to it, following the same principles as in quad_layout(). Otherwise, the stack_layout() itself is treated as the active layout, and the + operator will add elements directly to this plot.

circle_layout() works similarly to stack_layout(), but it does not support nested layouts. Therefore, the active layout in circle_layout() will always be the circle_layout() itself.

stack_alignh(small_mat) +
    align_dendro() +
    geom_point() +
    ggheatmap() +
    theme(axis.text.x = element_text(angle = -60, hjust = 0)) +
    anno_right() +
    align_dendro()
#> → heatmap built with `geom_tile()`

In quad_layout(), four nested layouts are available for annotations: top, left, bottom, and right. If no active annotation is set, quad_layout() treat itself as the active layout. Since there is only one main plot in the quad_layout(), the main plot is always treated as the active plot in this context. Otherwise, the active annotation is treated as the active layout, and the + operator will add elements to it, following the same principles as in stack_layout().

ggheatmap(small_mat) +
    scale_fill_viridis_c() +
    anno_left(size = 0.2) +
    align_dendro() +
    anno_right(size = 0.2) +
    align_dendro()
#> → heatmap built with `geom_tile()`

13.2 Logical AND Operator

&: applies elements to all plots in the layout including plots in the nested layout.

The & operator works similarly to patchwork, applying an element across all plots in a layout. Since & has lower precedence than +, it’s generally best to use it at the end of an expression or you should wrap it in parentheses when needed.

# Initialize the heatmap
ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    # Add a dendrogram in the left annotation and split the dendrogram into 3 groups
    align_dendro(aes(color = branch), k = 3L) +
    anno_right(size = 0.2) +
    # Add a dendrogram in the right annotation and split the dendrogram into 3 groups
    align_dendro(aes(color = branch), k = 3L) &
    # Set color scale for all plots
    scale_color_brewer(palette = "Dark2")
#> → heatmap built with `geom_tile()`

13.3 Subtraction Operator

The - operator is more powerful than the & operator, enabling flexible addition of elements to multiple plots, especially when working with Chapter 14. While its use might initially seem unintuitive, the reason behind this is that - shares the same precedence group as +, which allows it to seamlessly combine with +.

13.3.1 quad_layout()

For ggheatmap()/quad_layout(), if the active context is the ggheatmap()/quad_layout() itself (no active annotation), the - operator behaves similarly to &. It applies the specified elements to all plots within the layout.

# Initialize the heatmap
ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    anno_right(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # Remove any active annotation
    quad_active() -
    # Set color scale for all plots, since the active layout is the `ggheatmap()`/`quad_layout()`
    scale_color_brewer(palette = "Dark2")
#> → heatmap built with `geom_tile()`

If the active layout is an annotation stack, the - operator will only add the elements to all plots in the active annotation stack:

ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    align_dendro(aes(color = branch), k = 3L) -
    # Modify the the color scales of all plots in the left annotation
    scale_color_brewer(palette = "Dark2")
#> → heatmap built with `geom_tile()`

13.3.2 stack_layout()

For stack_layout(), if the active layout is the stack_layout() itself, - applies the elements to all plots in the layout except the nested ggheatmap()/quad_layout().

stack_alignv(small_mat) +
    align_dendro() +
    ggtitle("I'm from the parent stack") +
    ggheatmap() +
    # remove any active context
    stack_active() +
    align_dendro() +
    ggtitle("I'm from the parent stack") -
    # Modify the the color scales of all plots in the stack layout except the heatmap layout
    scale_color_brewer(palette = "Dark2") -
    # set the background of all plots in the stack layout except the heatmap layout
    theme(plot.background = element_rect(fill = "red"))
#> → heatmap built with `geom_tile()`

When the active layout is the nested ggheatmap()/quad_layout(), the - operator applies the elements to this nested layout, following the same principles as in the Section 13.3.1.

Want apply elements for plots in both stack_layout() and the nested ggheatmap()/quad_layout() at the same time? refer to the following section.

13.4 quad_scope()

The quad_scope() function adjusts the context in which elements are applied in ggheatmap()/quad_layout(). It allows you to control how objects such as themes, scales, and other plot elements are applied to specific annotation stacks or the main plot, without changing the currently active context.

This function accepts two arguments:

  1. x: An object which can be added to the plot.
  2. position: A string containing one or more of "t", "l", "b", "r", and "i" specifies the context for applying x.

13.4.1 quad_layout()

Default Behavior by wrapping object with quad_scope():

  • When ggheatmap()/quad_layout() has no active annotation stack, objects added via + or - operate normally without quad_scope().
  • When the active annotation stack is set, quad_scope() ensures the applied object also modifies:
    • The active annotation stack.
    • The main plot.

By wrapping object with quad_scope(), the + operator will apply the object not only to the active plot in the annotation stack, but also to the main plot.

ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro() +
    # apply the object not only to the active plot in the annotation stack, but
    # also to the main plot
    quad_scope(theme(plot.background = element_rect(fill = "red")))
#> → heatmap built with `geom_tile()`

By wrapping object with quad_scope(), the - operator will apply the object not only to the active annotation stack, but also to the main plot.

ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # Change the active layout to the left annotation
    anno_top(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    anno_bottom(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) -
    # Modify the theme of all plots in the bottom annotation in this way, and
    # the main plot
    quad_scope(theme(plot.background = element_rect(fill = "red")))
#> → heatmap built with `geom_tile()`

The position argument can be a string containing one or more of "t", "l", "b", "r", and "i", indicating which annotation stack should be used as the context or if it should be applied to the main plot.

ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # initialize the top annotation
    anno_top(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # initialize the bottom annotation
    anno_bottom(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) -
    # Modify the background of all plots in the left and top annotation
    quad_scope(theme(plot.background = element_rect(fill = "red")), "tl")
#> → heatmap built with `geom_tile()`

The position argument can also be NULL, which behaves as if no annotation is active.

ggheatmap(small_mat) +
    # initialize the left annotation
    anno_left(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # initialize the top annotation
    anno_top(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) +
    # initialize the bottom annotation
    anno_bottom(size = 0.2) +
    align_dendro(aes(color = branch), k = 3L) -
    # Modify the background of all plots
    quad_scope(theme(plot.background = element_rect(fill = "red")), NULL)
#> → heatmap built with `geom_tile()`

13.4.2 stack_layout()

For stack_layout(), if the active layout is the stack_layout() itself, - applies the elements to all plots in the layout and will apply it to the nested ggheatmap()/quad_layout() following the same principles as in quad_layout(). + won’t work.

When the active layout is the nested ggheatmap()/quad_layout(), the -/+ operator applies the elements to this nested layout, following the same principles of the nested layout.