İki grafik kenarını sola hizala (ggplot)


105

Ggplot kullanıyorum ve üst üste görüntülemek istediğim iki grafiğim var. grid.arrangeOnları istiflemek için gridExtra'dan kullandım . Sorun şu ki, eksen etiketleri ne olursa olsun grafiklerin sol kenarlarının yanı sıra sağ kenarlarının da hizalanmasını istiyorum. (sorun, bir grafiğin etiketlerinin kısa, diğerinin uzun olması nedeniyle ortaya çıkar).

Soru:
Bunu nasıl yapabilirim? Grid.arrange ile evli değilim ama ggplot2 bir zorunluluktur.

Denediğim şey:
2 x 2 ızgara yapmak için ncol ve nrow'un yanı sıra genişlik ve yükseklik ile oynamayı ve görselleri zıt köşelere yerleştirmeyi ve sonra genişliklerle oynamayı denedim ancak zıt köşelerde görselleri alamadım .

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)

görüntü açıklamasını buraya girin


2
İşte iki olası seçenek: burada ve burada .
— joran

@Joran Sol eksenlerin hizalanmasını arıyorum. Bunların işe yarayacağını sanmıyorum. Yine de yanılmak isterim.
— Tyler Rinker

Yanıtlar:


132

Bunu dene,

 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)

Düzenle

Burada, rbind.gtabledahil edilenin değiştirilmiş bir sürümünü kullanan daha genel bir çözüm (herhangi bir sayıda grafikle çalışır) .gridExtra

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

3
Güzel ve gerçekten oldukça yalındır. Çözüm için teşekkürler.
— Tyler Rinker

1
Mükemmel çözüm! Her arsadaki büyük özelleştirme nedeniyle fasetleme ile yapamayacağım birden fazla ayrı zaman serisi grafiğini hizalamak için bunun gibi bir şey arıyordum.
— wahalulu

İki sütunumuz olsaydı yüksekliği eşleştirmenin yolunun ne olacağını söyler misiniz? gA $ heights [2: 3] çalışmıyor gibi görünüyor. Grobun 2: 3'ten başka bir öğesini seçmem gerekir mi? Teşekkür ederim!
— Etienne Low-Décarie

4
Baptiste çözümün için teşekkürler. Ancak, arazilerden biri a tableGrob. gtable::cbindBana bir hayal kırıklığı hata veriyor: nrow(x) == nrow(y) is not TRUE. Baska öneri?
— Gabra

2
Bu çözüm benim için çalıştı, onu anlamaya çalışıyorum. Ne anlama geliyor [2:5]?
— Hurlikus

38

Bunu herhangi bir sayıdaki olay örgüsü için genellemek istedim. İşte Baptiste'in yaklaşımını kullanarak adım adım bir çözüm:

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

her grafiğin her bir parçası için genişlikleri toplayın

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

maksimum genişliği elde etmek için do.call kullanın

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

her bir grob için maksimum genişliği atayın

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

arsa

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

2
Arsaların çeşitli genişliklerde efsaneleri olsa bile işe yarar - çok güzel!
— Keith Hughitt

30

Cowplot paketini kullanma :

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")

görüntü açıklamasını buraya girin


12

Http://rpubs.com/MarkusLoew/13295 adresinde gerçekten kolay bir çözüm mevcut (son madde) Bu soruna uygulanan:

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"))

bunu hem genişlik hem de yükseklik için de kullanabilirsiniz:

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
kullanmak size="first", eğer ikinci olay birinciden daha büyükse hizalamanın çok iyi görünmeyeceği anlamına gelir
— baptiste

10

eggBir standart nesnelerini ggplot paketi saran 3x3yontulmuş da dahil olmak üzere rasgele ggplots arasında arsa panellerin uyum sağlayan 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)

görüntü açıklamasını buraya girin


benim için bu geom_tile, altta gösterge ve çok yönlü bir ısı haritası ( facet_gridile geom_tile) olan basit bir ısı haritasını ( ) yatay olarak düzgün bir şekilde düzenleyebilirdi , ancak bir dendrogram ( geom_segment) olan üçüncü grafiğin yüksekliğini hizalamayı başaramadı . ancak, inek planı ya gridExtra::grid.arrangeda eskisini bile yapamadı, bu yüzden bu şimdiye kadarki en iyi çalışıyor
— deeenes

8

meltReshape2 paketini kullanarak başka bir olası çözüm ve 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)

görüntü açıklamasını buraya girin


Bu çözüm, her sütunda eşit sayıda satırınız olduğunu varsayar. MRWE'mde bu doğru ama gerçekte değil.
— Tyler Rinker

Anladığımdan emin değilim: CO2 $ Plant ve CO2 $ Type'ın aynı uzunlukta olduğunu, ancak gerçek verilerinizin böyle olmadığını mı söylüyorsunuz?
— bdemarest

Bir değişkeni paylaşan iki farklı veri kümesidir, bu nedenle satır sayısı aynı değildir.
— Tyler Rinker

2

Patchwork paket varsayılan olarak bu işler:

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 tarihinde reprex paketi (v0.3.0) tarafından oluşturuldu


0

En iyi ihtimalle bu bir hack:

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

Yine de gerçekten yanlış geliyor.


-1

Bunun eski bir gönderi olduğunu ve zaten yanıtlanmış olduğunu biliyorum, ancak purrrdaha güzel görünmesi için @ baptiste'nin yaklaşımını birleştirmeyi önerebilir miyim :

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.