patchwork icon indicating copy to clipboard operation
patchwork copied to clipboard

Combine axes/scales

Open bwiernik opened this issue 5 years ago • 6 comments

I often have a case where I have two plots with the same y-axis scales that I would like to show side by side, with the axis only showing on the outer plot. Currently, I need to manually set the axis scales to be the same across plots and set the axis to be element_blank() for one of the plots.

Would it be possible to add functions to do these steps within the patchwork composition, similar to the legend collapsing?

bwiernik avatar Feb 17 '20 14:02 bwiernik

yes, that is on the roadmap, though I can't say when it will appear

thomasp85 avatar Jun 17 '20 17:06 thomasp85

+1 for this feature! But in the meantime, at least for axis labels, you can combine patchwork::patchworkGrob and gridExtra::grid.arrange as a workaround. Haven't tested it extensively, but seems to do OK as a first pass:

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) +
  aes(x = cyl, y = disp) +
  geom_point() +
  theme(axis.title = element_blank())

p2 <- p1 %+% aes(x = hp)

result <- p1 + p2
gt <- patchwork::patchworkGrob(result)
gridExtra::grid.arrange(gt, left = "Disp", bottom = "Hp // Cyl")

Created on 2020-09-22 by the reprex package (v0.3.0)

ashiklom avatar Sep 22 '20 21:09 ashiklom

+1. And if we stack plots on top of each other, it would be great if it's possible to put the common y-axis label in the middle.

tungttnguyen avatar Nov 05 '20 16:11 tungttnguyen

Hello! I tried to use the trick above but it doesn't play well with common legends!

image

PS: how can I get the same font of the ggplot plots with gridExtra

bakaburg1 avatar Aug 06 '21 18:08 bakaburg1

Any news on this feature?

hsantanna88 avatar Sep 03 '21 14:09 hsantanna88

+1 for this feature! But in the meantime, at least for axis labels, you can combine patchwork::patchworkGrob and gridExtra::grid.arrange as a workaround. Haven't tested it extensively, but seems to do OK as a first pass:

Isn't this a different issue?

If I understand correctly, OP is asking for an easy way to "share" an axis, so that two sub plots with very different y-axes but the same x-axis can easily get the same coord_cartesian(xlim = c(0, 40)) and the top subplot gets a theme(axis.title.text.x = element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank()), correct?

library(ggplot2)
library(patchwork)

pl_A <- iris |>
  ggplot(aes(x = Petal.Width, y = Petal.Length)) +
  geom_point() +
  labs(y = "Y axis label") +
  coord_cartesian(xlim = c(0, 3)) +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank())
pl_B <- iris |>
  ggplot(aes(x = Petal.Width, y = Sepal.Length)) +
  geom_point() +
  coord_cartesian(xlim = c(0, 3)) +
  scale_y_reverse("Different y axis label")
pl_A / pl_B

Created on 2022-03-09 by the reprex package (v2.0.1)

I also have an example in an upcoming workshop where we do this

japhir avatar Mar 09 '22 08:03 japhir

Any update on when collecting/combining the guides for y and x axes might be implemented?

bwiernik avatar Feb 07 '23 17:02 bwiernik

What's missing in the solution from @japhir is a bit more convenience in the very likely situation that the range on x is not the same in the subplots. If the package could take care of computing the x-range union internally (instead of requiring the manual min-max-madnaess with along with setting xlim via coord_cartesian), it would be just lovely. That's what imho the OP intends with sharing an axis.

The same argument would apply when sharing a y axis for sure.

holgerbrandl avatar Feb 17 '23 11:02 holgerbrandl

I might be interested in preparing a PR, but currently the following is unclear. There are two related but separate features proposed in this issue (discussed for y-axis, but x-axis should be opposite):

  • Deduplicate y-axis titles when subsequent plots in a horizontal direction have the same y-axis title.
  • Merge y-axis titles when subsequent plots in a vertical direction have the same y-axis title.

Both would be great additions, but these two goals can be add odds with one another. For example, in the plot below;

library(ggplot2)
library(patchwork)

p <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point()

p1 <- p + labs(y = "This is a shared axis title")
p2 <- p + labs(y = "This is a unique axis title") + 
  theme(axis.title.y = element_text(colour = 'red'))

p1 + p1 + p1 + p2 + plot_layout(nrow = 2)

Created on 2023-10-18 with reprex v2.0.2

The deduplication goal would see the y-axis title removed from the upper right plot. The merge goal would see the left y-axis titles merged. When we do both, we end up with one y-axis across the left and another just for the bottom-right plot. See image below for skilful use of MS paint to illustrate the idea.

image

Arguably though, it is slightly confusing since the left axis title seems to also apply to the bottom-right panel, whereas it doesn't (in a real scenario, it does for this dummy example). How should such a situation be resolved? Is this fine? Should merging get priority over deduplicating or vice versa?

teunbrand avatar Oct 18 '23 14:10 teunbrand

I would expect the title deduplication to apply to the top row but leave the bottom row untouched in that case

bwiernik avatar Oct 19 '23 00:10 bwiernik