Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axis panel size should be determind by its own axis label size #110

Closed
yiluheihei opened this issue Sep 18, 2019 · 7 comments
Closed

axis panel size should be determind by its own axis label size #110

yiluheihei opened this issue Sep 18, 2019 · 7 comments

Comments

@yiluheihei
Copy link

Thanks for your great work patchwork.

While vertical align two ggplots, the two axis panels of the two plots keep in the same size. It will generate unnecessary space in the axis panel, while the axis label of a plot is much longer then the other, e.g.

library(patchwork)
library(ggplot2)

p1 <- ggplot(diamonds, aes(clarity, price)) + 
  geom_boxplot() +
  coord_flip()

lev <- levels(diamonds$cut)
long_label <- paste("Very Very Very Very", lev)
names(long_label) <- lev
p2 <- ggplot(diamonds, aes(cut, price)) + 
  geom_boxplot() +
  scale_x_discrete(labels = long_label) + 
  coord_flip()

p1 + p2 + plot_layout(ncol = 1)

Created on 2019-09-19 by the reprex package (v0.3.0)

The figure I want to is shown as below

cowplot::plot_grid(p1, p2, ncol = 1)

Created on 2019-09-19 by the reprex package (v0.3.0)

Thanks.

@yiluheihei yiluheihei changed the title axis panel size should be determind by its own axis size while two plot vertical alignment axis panel size should be determind by its own axis label size Sep 18, 2019
@thomasp85
Copy link
Owner

This is really not what patchwork is about... the whole goal is to align plot areas.

That being said, you can achieve this using wrap_elements(), but the cowplot code is likely more readable 🤷‍♂️

wrap_elements(full = p1) + wrap_elements(full = p2) + plot_layout(ncol = 1)

image

@kendonB
Copy link

kendonB commented Apr 17, 2020

@thomasp85 I have a related issue to that here. How does one move the y-axis title close to the panel in patchwork? I still want the panels aligned but not the y-axis titles.

@thomasp85
Copy link
Owner

That is not possible and I’m not sure it ever will be

@LDSamson
Copy link

@thomasp85 I have a related issue to that here. How does one move the y-axis title close to the panel in patchwork? I still want the panels aligned but not the y-axis titles.

@kendonB You can edit the patchwork manually if you want with some trial and error, this worked for me: https://stackoverflow.com/a/62328273/11856430
In your, case, you should probably change the 'ylab-l' layout values (value 'l' (=left))

@joey711
Copy link

joey711 commented Jan 28, 2021

@thomasp85 @kendonB I think adding a negative margin theme spec works, provided you're willing to trial-and-error the margin needed to make it work. I added an example solution here: https://stackoverflow.com/questions/62304750/ignore-x-label-alignment-with-multiple-plots-in-patchwork-is-this-possible/62328273

@elong0527
Copy link

elong0527 commented Nov 7, 2021

How about using patchwork::inset_element?

library(ggplot2)
library(patchwork)

p1 <- ggplot(diamonds, aes(clarity, price)) + 
  geom_boxplot() +
  coord_flip()

lev <- levels(diamonds$cut)
long_label <- paste("Very Very Very Very", lev)
names(long_label) <- lev
p2 <- ggplot(diamonds, aes(cut, price)) + 
  geom_boxplot() +
  scale_x_discrete(labels = long_label) + 
  coord_flip()

p1 + p2 + plot_layout(ncol = 1)

text <- ggplot() + ylab("update label") +
  theme_bw(base_rect_size = 0) + 
  theme(
    panel.background = element_rect(fill = "transparent"), # bg of the panel
    plot.background = element_rect(fill = "transparent", color = NA), # bg of the plot
    panel.grid.major = element_blank(), # get rid of major grid
    panel.grid.minor = element_blank(), # get rid of minor grid
    legend.background = element_rect(fill = "transparent"), # get rid of legend bg
    legend.box.background = element_rect(fill = "transparent") # get rid of legend panel bg
  )
  
# 0.53 can be replaced to other font height and width ratio.
n_line <- max(nchar(as.character(p1$data$clarity))) * 0.53 + 1
p1 + inset_element(text, - unit(n_line, "line"), 0, 1, 1) + 
  p2 + 
  plot_layout(ncol = 1)

image

@TylerSagendorf
Copy link

TylerSagendorf commented May 27, 2022

@elong0527 You can also just modify p1 with annotation_custom as shown below

p1 <- ggplot(diamonds, aes(clarity, price)) + 
  geom_boxplot() +
  annotation_custom(grob = textGrob(
    label = "clarity",
    rot = 90, 
    gp = gpar(fontsize = 11),
    x = -40, default.units = "pt")
  ) +
  coord_flip(clip = "off") +
  theme(axis.title.y = element_blank())

This will place 11 point text 40 points before the x-axis (must include clip = "off" or the text outside of the plot area won't be visible). No need for inset_element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants