두 그래프 간선을 왼쪽 정렬 (ggplot)


105

저는 ggplot을 사용하고 있으며 서로 위에 표시하려는 두 개의 그래프가 있습니다. 나는 grid.arrangegridExtra에서 사용 하여 쌓았습니다. 문제는 축 레이블에 관계없이 그래프의 왼쪽 가장자리와 오른쪽 가장자리가 정렬되기를 원한다는 것입니다. (한 그래프의 레이블이 짧고 다른 그래프의 레이블이 길기 때문에 문제가 발생합니다).

질문 :
어떻게해야합니까? 나는 grid.arrange와 결혼하지 않았지만 ggplot2는 필수입니다.

내가 시도한 것 :
나는 2 x 2 그리드를 만들기 위해 너비와 높이, ncol 및 nrow를 사용하여 2 x 2 그리드를 만들고 비주얼을 반대쪽 모서리에 배치 한 다음 너비로 플레이했지만 반대쪽 모서리에서 비주얼을 얻을 수 없었습니다. .

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.arrange(A, B, ncol=1)

여기에 이미지 설명 입력


2
가능한 두 가지 옵션은 여기여기 입니다.
joran

@Joran 정렬 할 왼쪽 축을 찾고 있습니다. 나는 이것들이 그것을 할 것이라고 생각하지 않습니다. 그래도 나는 틀리고 싶다.
Tyler Rinker 2011

답변:


132

이 시도,

 gA <- ggplotGrob(A)
 gB <- ggplotGrob(B)
 maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
 gA$widths[2:5] <- as.list(maxWidth)
 gB$widths[2:5] <- as.list(maxWidth)
 grid.arrange(gA, gB, ncol=1)

편집하다

다음은에 rbind.gtable포함 된 수정 된 버전을 사용하는보다 일반적인 솔루션 (여러 플롯에서 작동) 입니다.gridExtra

gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))

3
아름답고 정말 꽤 솔직합니다. 해결책에 감사드립니다.
Tyler Rinker 2011

1
완벽한 솔루션! 각 플롯의 주요 사용자 지정으로 인해 패싯으로 할 수없는 여러 개의 개별 시계열 플롯을 정렬하기 위해 이와 같은 것을 찾고있었습니다.
wahalulu

두 개의 열이있는 경우 heigh를 일치시키는 방법이 무엇인지 친절하게 설명해 주시겠습니까? gA $ heights [2 : 3]가 작동하지 않는 것 같습니다. 2 : 3이 아닌 다른 grob 요소를 선택해야합니까? 감사합니다!
Etienne Low-Décarie 2013-06-28

4
Baptiste 솔루션에 감사드립니다. 그러나 플롯 중 하나가 tableGrob. 은 gtable::cbind나에게 실망 오류를 제공합니다 nrow(x) == nrow(y) is not TRUE. 어떤 제안?
Gabra

2
이 솔루션은 나를 위해 일했으며 이해하려고 노력하고 있습니다. 뭐라고합니까 [2:5]약자?
Hurlikus

38

나는 이것을 여러 플롯에 대해 일반화하고 싶었습니다. 다음은 Baptiste의 접근 방식을 사용한 단계별 솔루션입니다.

plots <- list(A, B, C, D)
grobs <- list()
widths <- list()

각 플롯의 각 grob에 대한 너비 수집

for (i in 1:length(plots)){
    grobs[[i]] <- ggplotGrob(plots[[i]])
    widths[[i]] <- grobs[[i]]$widths[2:5]
}

do.call을 사용하여 최대 너비를 얻으십시오.

maxwidth <- do.call(grid::unit.pmax, widths)

각 grob에 최대 너비를 할당하십시오.

for (i in 1:length(grobs)){
     grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}

음모

do.call("grid.arrange", c(grobs, ncol = 1))

2
플롯에 다양한 너비의 범례가있는 경우에도 작동합니다. 매우 좋습니다!
Keith Hughitt

30

cowplot 패키지 사용 :

A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 

library(cowplot)
plot_grid(A, B, ncol=1, align="v")

여기에 이미지 설명 입력


12

http://rpubs.com/MarkusLoew/13295는 이 문제에 사용할 수있는 정말 쉬운 솔루션 (마지막 항목) 적용은 다음과 같습니다

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first"))

너비와 높이 모두에 사용할 수도 있습니다.

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip()
D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip() 
grid.draw(cbind(
            rbind(ggplotGrob(A), ggplotGrob(B), size="first"),
            rbind(ggplotGrob(C), ggplotGrob(D), size="first"),
            size='first'))

2
using size="first"은 두 번째 줄거리가 첫 번째 줄보다 크면 정렬이 잘 보이지 않을 것임을 의미합니다
baptiste

10

egg표준화에 객체 ggplot 패키지 랩 3x3각면 포함한 임의의 ggplots 사이 플롯 패널의 정렬을 가능하게 gtable.

library(egg) # devtools::install_github('baptiste/egg')
library(ggplot2)

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() 

p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") +
  guides(colour="none") +
  theme()

ggarrange(p1, p2)

여기에 이미지 설명 입력


나를 위해 이것은 geom_tile하단에 범례가 있는 간단한 히트 맵 ( )과 다면적 히트 맵 ( facet_grid사용 geom_tile)을 수평으로 적절하게 정렬 할 수 있었지만 덴드로 그램 ( geom_segment) 인 세 번째 플롯의 높이를 정렬하지 못했습니다 . 그러나 cowplot 또는 gridExtra::grid.arrange전자조차 할 수 없었기 때문에 이것은 지금까지 가장 잘 작동합니다
deeenes

8

meltreshape2 패키지에서 사용 하는 또 다른 가능한 솔루션은 다음 과 facet_wrap같습니다.

library(ggplot2)
library(reshape2)

dat = CO2[, c(1, 2)]
dat$id = seq(nrow(dat))
mdat = melt(dat, id.vars="id")

head(mdat)
#   id variable value
# 1  1    Plant   Qn1
# 2  2    Plant   Qn1
# 3  3    Plant   Qn1
# 4  4    Plant   Qn1
# 5  5    Plant   Qn1
# 6  6    Plant   Qn1

plot_1 = ggplot(mdat, aes(x=value)) + 
         geom_bar() + 
         coord_flip() +
         facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE)

ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6)

여기에 이미지 설명 입력


이 솔루션은 각 열에 동일한 수의 행이 있다고 가정합니다. 내 MRWE에서는 사실이지만 실제로는 그렇지 않습니다.
Tyler Rinker 2011

잘 모르겠습니다. CO2 $ Plant와 CO2 $ Type의 길이가 같지만 실제 데이터가 그렇지 않다는 뜻입니까?
bdemarest 2011

하나의 변수를 공유하는 두 개의 다른 데이터 세트이므로 행 수가 동일하지 않습니다.
Tyler Rinker 2012

2

패치 워크 패키지는 기본적으로이 문제를 처리합니다

library(ggplot2)
library(patchwork)

A <- ggplot(CO2, aes(x = Plant)) + geom_bar() + coord_flip() 
B <- ggplot(CO2, aes(x = Type)) + geom_bar() + coord_flip() 

A / B

2019-12-08에 reprex 패키지 (v0.3.0)로 생성됨


0

기껏해야 이것은 해킹입니다.

library(wq)
layOut(list(A, 1, 2:16),  list(B, 2:3, 1:16))

그래도 정말 잘못된 느낌입니다.


-1

나는 이것이 오래된 게시물이고 이미 답변을 받았음을 알고 있지만 @baptiste의 접근 방식을 purrr더 멋지게 만들기 위해 결합하는 것이 좋습니다 .

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.