2013-06-17 29 views
16

Tôi có hai đồ thị mà tôi đang đặt chồng lên nhau, theo cách sau:ggplot2 và gridExtra: hoàn toàn loại bỏ dải trong facet_grid - không chỉ vô hình

library(ggplot2) 
library(gridExtra) 
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 
p2 <- p2 + facet_grid(cyl ~ .) 
grid.arrange(p1, p2, ncol=1) 

Đối với điều này tôi cần các trục x của các biểu đồ trên cùng và dưới cùng để xếp hàng, tuy nhiên do dải ở bên trái, biểu đồ hình tròn hẹp hơn biểu đồ trên cùng. Tôi có thể làm cho dải không nhìn thấy được bằng cách sử dụng:

theme(strip.text.y = element_blank()) 
theme(strip.background = element_blank()) 

Tuy nhiên điều này không loại bỏ được khoảng trống mà dải đó chiếm. Vì vậy, tôi cần một cách để thoát khỏi dải hoàn toàn, hoặc có một cách để phân chia biểu đồ mặt của tôi thành các đồ thị riêng biệt, nhưng bằng cách nào đó chia sẻ cùng một nhãn y-trục trên chúng. Trong biểu đồ của tôi, tôi có hai mặt bảng không phải là rất cao, và không có đủ không gian cho mỗi cái có một trục y có kích thước khá.

Mọi đề xuất?

+0

Cách giải quyết khác của tôi (trong mạng, nơi tôi thông thạo hơn) là thêm dải vào ô "đơn giản". –

Trả lời

8

Giải pháp của tôi là tìm chiều rộng của dải và sau đó đặt lề của cả hai ô bằng 0, nhưng thu nhỏ dải không có dải nhỏ hơn (chiều rộng của dải) sao cho chúng xuất hiện có cùng kích thước. Bằng thử nghiệm và lỗi có vẻ như dải là khoảng 0,5 dòng rộng (nhưng tôi đoán bạn có thể con số này ra programatically). Do đó chỉ cần đảm bảo lề âm mưu ngay trong cốt truyện mà không văn bản dải là 0,5 dòng lớn hơn một với dải vô hình:

# Add a line of width 0.5 on the left but set all other margins to zero 
p1 <- p1 + theme(plot.margin = unit(c(0,0.5,0,0) , units = "lines")) 
# Set all margins to zero, the strip will take up a phantom amount of invisible space 
p2 <- p2 + theme(strip.text.y = element_blank() , 
    strip.background = element_blank(), 
    plot.margin = unit(c(0,0,0,0) , units = "lines")) 

grid.arrange(p1, p2, ncol=1) 

Rõ ràng, bạn có thể điều chỉnh lề như bạn muốn (ví dụ thêm 1 tới vị trí đầu tiên trong mỗi vector số trong plot.margin để có được đường viền của một dòng dọc theo đầu mỗi ô), miễn là bạn giữ 0,5 đường lề nhiều hơn ở biên phải của ô thứ hai, chúng sẽ trông giống nhau.

enter image description here

+0

Điều đó hoàn hảo, cảm ơn bạn! –

+0

@ClaireArmstrong bạn rất hoan nghênh! :-) –

1

đây một giải pháp sử dụng viewportgrid.layout. Tôi tạo ra 2 viewports với 2 bố cục khác nhau. Sau đó, tôi đặt các ô ggplot2 bằng cách sử dụng đối số vp.

library(grid) 
pushViewport(plotViewport(c(1,1,1,1),layout = grid.layout(2, 1))) 
print(p2, vp = viewport(layout.pos.row = 2, layout.pos.col = 1)) 
pushViewport(viewport(layout.pos.row=1, 
    layout = grid.layout(1, 2,widths = unit(c(1,1),c("null",'lines'))))) 
print(p1, vp = viewport(layout.pos.row = 1, layout.pos.col = 1)) 
upViewport(2)    

enter image description here

1

Bạn cũng có thể làm theo cách này và giữ các chức danh dải, đó sẽ là thông tin thích hợp:

library(ggplot2) 
library(gridExtra) 
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() + 
     xlab(NULL) 
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() + 
     facet_wrap(~ cyl, ncol = 1) 
grid.arrange(p1, p2, ncol=1) 
1

Một giải pháp khác sử dụng chức năng từ gói gtable. Nó sắp xếp các ô nhưng giữ văn bản dải. Nó sử dụng hàm gtable để chèn cột ở bên phải p1 bằng với chiều rộng của văn bản dải là p2.

library(ggplot2) 
library(gridExtra) 
library(gtable) 

p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 
p2 <- p2 + facet_grid(cyl ~ .) 

g1 = ggplotGrob(p1) 
# gtable_show_layout(g1) # View the layout 
# g1$widths    # Get the widths of g1 

g2 = ggplotGrob(p2) 
# gtable_show_layout(g2) # View the layout 
# g2$widths    # Check the widths of g2 

# Add new column to the right of g1 equal in width the strip width of g2. 
# In g2, strip width is the 5th element the vector g2$widths 
g1 <- gtable_add_cols(g1, g2$widths[5]) 
grid.arrange(g1, g2, ncol=1) 

enter image description here

## But note that if the y-axis titles and/or labels take up different widths, 
# the two plots are not aligned 
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() + 
    theme(axis.title.y = element_text(angle = 0, size = 30)) 
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() 
p2 <- p2 + facet_grid(cyl ~ .) 

g1 = ggplotGrob(p1) 
g2 = ggplotGrob(p2) 

g1 <- gtable_add_cols(g1, g2$widths[5]) # New column added to the right 
grid.arrange(g1, g2, ncol=1)    # Plots are not aligned 

enter image description here

# Need to set widths to the maximums in the two plots, 
# i.e., set g2 widths to be the same as g1 widths 
g2$widths <- g1$widths 
grid.arrange(g1, g2, ncol=1)   # Plots are aligned 

enter image description here

EDIT: Hoặc theo đề nghị của Baptiste, sử dụng gtable 's rbind() chức năng:

g1 = ggplotGrob(p1) 
g2 = ggplotGrob(p2) 

g1 <- gtable_add_cols(g1, g2$widths[5], 4) # New column added to the right 

library(grid) 
grid.draw(rbind(g1, g2, size = "first")) 
+0

thay vì 'grid.arrange()', tôi khuyên bạn nên 'grid.draw (rbind (g1, g2))'. Nhưng bạn cần một [phiên bản dev của gtable] (https://github.com/baptiste/gtable) (và R-devel cho bây giờ), nếu không rbind không so sánh chiều rộng. – baptiste

Các vấn đề liên quan