Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontal alignment of colour scales in patchwork

I'm using the package patchwork to combine multiple ggplot2 plots vertically. I'd like the scales for each plot to be directly above one another, regardless of the length of the scale name. At the moment, the scales are not aligned above one another.

I'm open to using ggpubr or facet_grid() if they would make it possible, but I've seen that facets doesn't allow multiple scales, and I haven't found any solution using ggpubr

library(ggplot2)
library(patchwork)

set.seed(0)
testdata <- data.frame(x=1:10, y=1:10, col=runif(10))

g1 <- ggplot(testdata, aes(x=x,y=y,col=col)) + geom_point() + 
  scale_color_gradient(name="Short")
g2 <- ggplot(testdata, aes(x=x,y=y,col=col)) + geom_point() + 
  scale_color_gradient(name="A rather longer name")
g1/g2

ggsave("testfile.tiff", units = "mm", device="tiff", 
       width=100, height=100, dpi = 100)

Example plot with scales not aligned

Ideal output:

Example plot with scales aligned

like image 291
Miff Avatar asked Oct 14 '25 08:10

Miff


2 Answers

With plot_layout you can "collect" the legends. This uses as default theme(legend.position = 'right'). You can add this after plot_layout with & theme(legend.position = 'right') and adjust the position if you want to change the location of the legends.

g1/g2 + plot_layout(guides = 'collect') # & theme(legend.position = 'right') <- adjust position here!

ggsave("testfile.tiff", units = "mm", device="tiff", 
       width=100, height=100, dpi = 100)  

enter image description here

like image 96
phiver Avatar answered Oct 18 '25 02:10

phiver


I'd also be curious to learn of a patchwork parameter than could fix this, but I don't think there is one (please correct me if I'm wrong). You may have noticed that Hadley's answer is more than 10 years old and people have been working on ggplot2 since then. The ggnewscale package solves the problem of having multiple scales per plot. Here is a facetted approach using multiple colourscales:

library(ggplot2)
library(ggnewscale)

set.seed(0)
testdata <- data.frame(x=1:10, y=1:10, col=runif(10))

ggplot(mapping = aes(x = x, y, y)) +
  geom_point(data = transform(testdata, 
                              facet = factor("Top", c("Top", "Bottom"))),
             aes(colour = col)) +
  scale_colour_continuous(name = "Short") +
  new_scale_colour() +
  geom_point(data = transform(testdata,
                              facet = factor("Bottom", c("Top", "Bottom"))),
             aes(colour = col)) +
  scale_colour_continuous(name = "A rather longer name") +
  facet_wrap(~ facet, ncol = 1)

like image 26
teunbrand Avatar answered Oct 18 '25 02:10

teunbrand