Skip to content

Allow missing tag level #147

Description

@jeanettelt

Hi there,

My project team and I have found this package much more useful and intuitive than cowplot, so thank you!

We've been using patchwork to combine multiple plots into one figure. Our largest figure is a 3x3 grid where each plot is a combined 2x1 plot, so there's actually a total of 18 ggplot objects.

We were hoping to use the plot_layout(tag_level = 'new') feature to skip labeling our subplots, but the skipped subplots also skip the associated label letters. Here is a simplified example:

library(tidyverse)
library(patchwork)
p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + ggtitle("Main plot 1")
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) + ggtitle("Main plot 2")
h1 <- ggplot(mtcars) + geom_histogram(aes(mpg)) + plot_layout(tag_level = 'new') + ggtitle("Subplot 1")
h2 <- ggplot(mtcars) + geom_histogram(aes(gear)) + scale_x_continuous(limits = c(2.5, 5.5), expand = c(0, 0)) + ggtitle("Subplot 2") + plot_layout(tag_level = 'new')
((p1 / h1) | (p2 / h2)) + plot_annotation(tag_levels = c('A'))
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> Warning: Removed 2 rows containing missing values (geom_bar).

Created on 2020-01-17 by the reprex package (v0.3.0)

We've instead used ggplot2's labs(title = ) feature, like in the modified example below, to manually create labels for our nine plots, but were hoping for a simpler solution through patchwork.

library(tidyverse)
library(patchwork)
p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + ggtitle("Main plot 1")
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) + ggtitle("Main plot 2")
h1 <- ggplot(mtcars) + geom_histogram(aes(mpg)) + plot_layout(tag_level = 'new') + ggtitle("Subplot 1")
h2 <- ggplot(mtcars) + geom_histogram(aes(gear)) + scale_x_continuous(limits = c(2.5, 5.5), expand = c(0, 0)) + ggtitle("Subplot 2")
(((p1 + labs(title = "A")) / h1) | ((p2 + labs(title = "B")) / h2))
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> Warning: Removed 2 rows containing missing values (geom_bar).

Created on 2020-01-17 by the reprex package (v0.3.0)

Activity

  1. kendonB commented on Mar 2, 2021

    @kendonB

    @thomasp85 this fix fails in the special case where the user arranges the plots using the + operator for the first plot:

    library(tidyverse)
    library(patchwork)
    p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + ggtitle("Main plot 1")
    p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) + ggtitle("Main plot 2")
    h1 <- ggplot(mtcars) + geom_histogram(aes(mpg)) + plot_layout(tag_level = 'new') + ggtitle("Subplot 1")
    h2 <- ggplot(mtcars) + geom_histogram(aes(gear)) + scale_x_continuous(limits = c(2.5, 5.5), expand = c(0, 0)) + ggtitle("Subplot 2") + plot_layout(tag_level = 'new')
    
    h1 + h2 + p1 + p2 + plot_annotation(tag_levels = c('A'))
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> Warning: Removed 2 rows containing missing values (geom_bar).

    Created on 2021-03-03 by the reprex package (v1.0.0)

  2. kendonB commented on Mar 2, 2021

    @kendonB

    A bit of a hack is the following solution using the text-based layout feature:

    library(tidyverse)
    library(patchwork)
    p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + ggtitle("Main plot 1")
    p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear)) + ggtitle("Main plot 2")
    h1 <- ggplot(mtcars) + geom_histogram(aes(mpg)) + plot_layout(tag_level = 'new') + ggtitle("Subplot 1")
    h2 <- ggplot(mtcars) + geom_histogram(aes(gear)) + scale_x_continuous(limits = c(2.5, 5.5), expand = c(0, 0)) + ggtitle("Subplot 2") + plot_layout(tag_level = 'new')
    layout = "
              CD
              AB
             "
    p1 + p2 + h1 + h2 + plot_annotation(tag_levels = c('A')) + plot_layout(design = layout)
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> Warning: Removed 2 rows containing missing values (geom_bar).

    Created on 2021-03-03 by the reprex package (v1.0.0)

  3. kendonB commented on May 3, 2023

    @kendonB

    @thomasp85 I landed here from Google, just adding the syntax that took me a while to figure out:

    plot_annotation(tag_levels = list(c("A", "B", "C", "D", "E")))
    

    This, for example, deletes the F if it were there

  4. iamakhilverma commented on Oct 18, 2023

    @iamakhilverma

    @thomasp85 I landed here from Google, just adding the syntax that took me a while to figure out:

    plot_annotation(tag_levels = list(c("A", "B", "C", "D", "E")))
    

    This, for example, deletes the F if it were there

    Good hack, Thanks a lot!
    For me ignore_tag = T wasn't working as intended, so, used this hack to modify my annotation to exclude the insets-

    plot_annotation(tag_levels = list(c("A", "", "B", "", "C", "", "D", "", "E", "", "F", "", "G", "H")))

  5. ResidentialDragonSlayer commented on Mar 23, 2026

    @ResidentialDragonSlayer

    Coming late to this discussion, but I ran into kendonB's issue while creating a paneled figure where panels A and B had insets. My initial code:

    `panelA <- figA + inset_element(figA_inset, ignore_tag=T)
    panelB <- figB + inset_element(figB_inset, ignore_tag=T)

    panelA + panelB + panelC + panelD +
    plot_annotation(tag_levels = 'A')`

    resulted in no annotations on panels A or B and labeled the bottom panels as A and B.

    Doing it all at one patchwork level:

    figA + inset_element(figA_inset, ignore_tag=T) + figB + inset_element(figB_inset, ignore_tag=T) + panelC + panelD + plot_annotation(tag_levels = 'A')

    fixed the issue. (I initially tried iamakhilverma's workaround, which fixed the main plot beautifully, but created spaces in my insets where the empty labels should have gone and changed aspect ratios.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions