Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly combine two ggplots and properly align axis and strips/titles?

I need to combine two ggplots. They should have labels (A, B, and C) as for being used in a publication. The first plot is a facet_wrap(). This is my code:

library(ggplot2)
library(dplyr)
library(patchwork)

# First plot with facets
p1 <- ggplot(mtcars %>%
               filter(cyl %in% c("4", "6")) %>%
               mutate(cyl_label=paste0("label_", cyl)), 
             aes(x=mpg, y=wt)) +
  geom_point() +
  theme_bw() +
  theme(aspect.ratio = 2,
        strip.text.x = element_text(hjust = 0, colour = "black", size = 14,
                                    margin = unit(c(t=0.15,r=0,b=0.15,l=0), "cm")),
    strip.background = element_blank()) +
  facet_wrap(~ cyl_label, 
             labeller = labeller(cyl_label = c(label_4 = "(A) First plot",
                                               label_6 = "(B) Second plot"))) +
  theme(aspect.ratio = 2)

# Second plot with title
p2 <- ggplot(mtcars, aes(x=hp, y=wt)) +
  geom_point() +
  ggtitle("(C) Third plot") +
  theme_bw() +
  theme(
    aspect.ratio = 1, 
    plot.title = element_text(hjust = 0, colour = "black", size = 14,
                              margin = unit(c(t=0.15,r=0,b=0.15,l=0), "cm")))

# Combine plots side by side
combined_plot <- p1 + p2 + 
  plot_layout(ncol = 2) 

This is the plot I got:

The combined plot have two issues:

  1. The "(C)" label is not aligned, and
  2. the y dimension of both plots is not aligned.

Interestingly, the second plot by itself has the title in the correct position:

like image 825
Giuseppe Petri Avatar asked Dec 02 '25 22:12

Giuseppe Petri


2 Answers

patchwork tries to makes the titles line up with titles and facets line up with facets. Since you are trying to mix and match, that's confusing. So why not use a facet for the third label

p1 <- ggplot(mtcars %>%
               filter(cyl %in% c("4", "6")) %>%
               mutate(cyl_label=paste0("label_", cyl)), 
             aes(x=mpg, y=wt)) +
  geom_point() +
  theme_bw() +
  theme(
    strip.text.x = element_text(hjust = 0, colour = "black", size = 14, margin = unit(c(t=0.15,r=0,b=0.15,l=0), "cm")),
    strip.background = element_blank()
  ) +
  facet_wrap(~ cyl_label, 
             labeller = labeller(cyl_label = c(label_4 = "(A) First plot", label_6 = "(B) Second plot")))

p1

# Second plot with title
p2 <- ggplot(mtcars, aes(x=hp, y=wt)) +
  geom_point() +
  theme_bw() +
  theme(
    strip.text.x = element_text(hjust = 0, colour = "black", size = 14, margin = unit(c(t=0.15,r=0,b=0.15,l=0), "cm")),
    strip.background = element_blank()
  ) +
  facet_wrap(~"(C) Third Plot") 

p2

# Combine plots side by side
combined_plot <- p1 + p2 + 
  plot_layout(ncol = 2) 

combined_plot

enter image description here

Is the aspect ratio part required? It seems to interfere a bit with getting the bounding boxes to line up with each other. I wasn't sure if you were just trying to squeeze the first two plots together or if you needed a particular aspect ratio.

like image 116
MrFlick Avatar answered Dec 05 '25 11:12

MrFlick


patchwork's free() lets you remove the alignment, so you could do

(free(
  p1 + ylim(0, 6)
) |
  free(
    p2 + ylim(0, 6) + theme_bw()
  )) &
  theme(
    plot.title = element_text(
      hjust = 0,
      colour = "black",
      size = 14,
      margin = unit(c(t = 0.15, r = 0, b = 0.15, l = 0), "cm")
    ),
    strip.text.x = element_text(
      hjust = 0,
      colour = "black",
      size = 14,
      margin = unit(c(t = 0.15, r = 0, b = 0.15, l = 0), "cm")
    ),
    strip.background = element_blank()
  )

enter image description here

like image 27
Michiel Duvekot Avatar answered Dec 05 '25 11:12

Michiel Duvekot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!