2012-10-30 23 views
15

Tiêu đề khá phù hợp với nó.Làm cách nào để tôi định vị hai huyền thoại độc lập trong ggplot

Tôi có hai truyền thuyết, liên quan đến kích thước và màu sắc, và muốn có một, ví dụ, trên đầu và một trong biểu đồ.

Đây có phải là tốt, và nếu như vậy, như thế nào

TIA

+0

Tôi không nghĩ điều đó là có thể (nơi các truyền thuyết được đặt được điều khiển bởi chủ đề, và những phần xác định vị trí chú thích chỉ có một giá trị duy nhất). Tuy nhiên, tôi không chắc chắn rằng nó không thể làm cho câu trả lời này. –

+0

Đoán xem đó có phải là một trong những chuyên gia đã có ngay bây giờ là – pssguy

+0

@pssguy, nó có thể được thực hiện với một số không quan trọng. Để có quyền kiểm soát các truyền thuyết, bạn cần phải trích xuất các truyền thuyết riêng biệt, sau đó chúng có thể được sắp xếp trong một âm mưu ban đầu không chứa chú thích. –

Trả lời

3

Từ hiểu biết của tôi, về cơ bản có kiểm soát rất hạn chế so với huyền thoại trong ggplot2. Đây là một đoạn trong sách của Hadley (trang 111):

ggplot2 cố gắng sử dụng số lượng nhỏ nhất có thể của truyền thuyết để truyền tải chính xác tính thẩm mỹ được sử dụng trong cốt truyện. Nó thực hiện điều này bằng cách kết hợp các truyền thuyết nếu một biến được sử dụng với nhiều hơn một thẩm mỹ. Hình 6.14 cho thấy một ví dụ về điều này cho các điểm geom: nếu cả hai màu sắc và hình dạng được ánh xạ tới cùng một biến, thì chỉ một chú giải đơn là cần thiết. Để các truyền thuyết được hợp nhất, chúng phải có cùng tên (cùng một tiêu đề chú giải). Vì lý do này, nếu bạn thay đổi tên của một trong các truyền thuyết đã hợp nhất, bạn cần thay đổi nó cho tất cả các truyền thuyết.

+0

Cảm ơn bạn đã trích xuất. Tất cả các ví dụ cho thấy truyền thuyết ở cùng một vị trí – pssguy

28

Có thể thực hiện bằng cách trích xuất các truyền thuyết riêng biệt từ ô, sau đó sắp xếp các chú thích trong ô có liên quan. Mã ở đây sử dụng các hàm từ gói gtable để thực hiện việc trích xuất, sau đó thực hiện các chức năng từ gói gridExtra để thực hiện sắp xếp. Mục đích là để có một âm mưu có chứa một huyền thoại màu và một chú thích kích thước. Đầu tiên, trích xuất chú giải màu từ một ô chỉ chứa chú thích màu. Thứ hai, trích xuất chú giải kích thước từ một ô chứa chỉ chú thích kích thước. Thứ ba, vẽ một cốt truyện không chứa chú thích. Thứ tư, sắp xếp cốt truyện và hai truyền thuyết thành một cốt truyện mới.

# Some data 
df <- data.frame(
    x = 1:10, 
    y = 1:10, 
    colour = factor(sample(1:3, 10, replace = TRUE)), 
    size = factor(sample(1:3, 10, replace = TRUE))) 

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

    ### Step 1 
# Draw a plot with the colour legend 
(p1 <- ggplot(data = df, aes(x=x, y=y)) + 
    geom_point(aes(colour = colour)) + 
    theme_bw() + 
    theme(legend.position = "top")) 

# Extract the colour legend - leg1 
leg1 <- gtable_filter(ggplot_gtable(ggplot_build(p1)), "guide-box") 

    ### Step 2 
# Draw a plot with the size legend 
(p2 <- ggplot(data = df, aes(x=x, y=y)) + 
    geom_point(aes(size = size)) + 
    theme_bw()) 

# Extract the size legend - leg2 
leg2 <- gtable_filter(ggplot_gtable(ggplot_build(p2)), "guide-box") 

    # Step 3 
# Draw a plot with no legends - plot 
(plot <- ggplot(data = df, aes(x=x, y=y)) + 
    geom_point(aes(size = size, colour = colour)) + 
    theme_bw() + 
    theme(legend.position = "none")) 

    ### Step 4 
# Arrange the three components (plot, leg1, leg2) 
# The two legends are positioned outside the plot: 
# one at the top and the other to the side. 
plotNew <- arrangeGrob(leg1, plot, 
     heights = unit.c(leg1$height, unit(1, "npc") - leg1$height), ncol = 1) 

plotNew <- arrangeGrob(plotNew, leg2, 
      widths = unit.c(unit(1, "npc") - leg2$width, leg2$width), nrow = 1) 

grid.newpage() 
grid.draw(plotNew) 

# OR, arrange one legend at the top and the other inside the plot. 
plotNew <- plot + 
     annotation_custom(grob = leg2, xmin = 7, xmax = 10, ymin = 0, ymax = 4) 

plotNew <- arrangeGrob(leg1, plotNew, 
    heights = unit.c(leg1$height, unit(1, "npc") - leg1$height), ncol = 1) 

grid.newpage() 
grid.draw(plotNew) 

enter image description here

enter image description here

+0

Xin chào Sandy. Đây là một ví dụ ấn tượng. Bạn có thể chia nhỏ logic về việc sử dụng đối số 'heights' thành' arrangGrob', ví dụ trong 'plotNew <- arrangGrob (leg1, plot, heights = unit.c (leg1 $ height, unit (1," npc ")) - leg1 $ height), ncol = 1) '? Tôi nhận được rằng 'heights' được thông qua như một đối số cho' grid.layout', nhưng tôi gặp khó khăn khi thấy nó được sử dụng ở đây như thế nào. Cảm ơn. –

+0

Hi @Faheem, Có hai ô được sắp xếp theo chiều dọc: 'leg1' và' plot'; và do đó có hai chiều cao trong hàm 'unit.c()'. 'leg1' có chiều cao tuyệt đối và được cho bởi' leg1 $ height'. Chiều cao thứ hai, 'đơn vị (1," npc ") - leg1 $ height', trừ chiều cao chú thích từ độ cao của thiết bị để cung cấp chiều cao có sẵn cho' ô'. Trong ví dụ đầu tiên, một logic tương tự áp dụng cho độ rộng. Có hai rãnh để được vẽ: cốt truyện và truyền thuyết. Do đó hai chiều rộng trong hàm 'unit.c()'; một cho 'plotNew' và thứ hai cho' leg2'. –

+0

Cảm ơn, Sandy. Một câu hỏi nữa - làm thế nào để bạn biết chiều cao của thiết bị là 'đơn vị (1," npc ")'? Sẽ hữu ích nếu bạn thêm một số thông tin này vào câu hỏi của mình. Bạn có thể đề cập đến (a) đối số 'heights' và' widths' được chuyển tới 'grid.layout', (b) rằng' đơn vị (1, "npc") 'là chiều cao của thiết bị, và do đó (c) ví dụ 'leg1 $ height' và' unit (1, "npc") - leg1 $ height' là chiều cao của chú giải và cốt truyện chính tương ứng. Tôi có thể thêm điều này nếu bạn muốn. –

6

Dưới đây là một giải pháp sử dụng ggplot2cowplot (= mở rộng ggplot2) gói.

Phương pháp này tương tự như phương pháp Sandys khi nó đưa ra chú giải là các đối tượng riêng biệt và cho phép bạn thực hiện vị trí độc lập. Nó được thiết kế sơ bộ cho nhiều truyền thuyết thuộc về hai hoặc nhiều ô trong một ô lưới.

Chức năng g_legend, được sử dụng herby, được lấy từ answer này.

Ý tưởng là như sau:

  1. Tạo Plot1, Plot2, ..., PlotX mà không huyền thoại
  2. Tạo Plot1, Plot2, ..., PlotX với huyền thoại
  3. Extract huyền thoại từ bước 2 thành các đối tượng riêng biệt
  4. Thiết lập lưới huyền thoại và sắp xếp huyền thoại họ theo cách bạn muốn
  5. Tạo lưới kết hợp lô và truyền thuyết

Dường như kinda phức tạp và thời gian/mã comsuming nhưng thiết lập một lần, bạn có thể thích ứng và sử dụng nó cho tất cả các loại tùy chỉnh âm mưu/truyền thuyết.

library(ggplot2) 
library(cowplot) 

# set up function 
g_legend<-function(a.gplot){ 
    tmp <- ggplot_gtable(ggplot_build(a.gplot)) 
    leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") 
    legend <- tmp$grobs[[leg]] 
    return(legend) } 

# Some data 
df <- data.frame(
    Name = factor(rep(c("A", "B", "C"), 12)), 
    Month = factor(rep(1:12, each=3)), 
    Temp = sample(0:40, 12), 
    Precip = sample(50:400, 12)) 

# create plot1 
plot1 <- ggplot(df, aes(Month, Temp, fill = Name)) + 
    geom_point(show.legend = F, aes(group = Name, colour = Name), 
     size = 3, shape = 17) + 
    geom_smooth(method = "loess", se = F, 
     aes(group = Name, colour = Name), 
     show.legend = F, size = 0.5, linetype = "dashed") 

# create plot2 
plot2 <- ggplot(df, aes(Month, Precip, fill = Name)) + 
    geom_bar(stat = "identity", position = "dodge", show.legend = F) + 
    geom_smooth(method = "loess", se = F, 
     aes(group = Name, colour = Name), 
     show.legend = F, size = 1, linetype = "dashed") + 
    scale_fill_grey() 

# create legend1 
legend1 <- ggplot(df, aes(Month, Temp)) + 
    geom_point(show.legend = T, aes(group = Name, colour = Name), 
     size = 3, shape = 17) + 
    geom_smooth(method = "loess", se = F,aes(group = Name, colour = Name), 
     show.legend = T, size = 0.5, linetype = "dashed") + 
    labs(colour = "Station") + 
    theme(legend.text=element_text(size=8), 
      legend.title = element_text(face = "italic", 
       angle = -0, size = 10)) 

# create legend2 
legend2 <- ggplot(df, aes(Month, Precip, fill = Name)) + 
    geom_bar(stat = "identity", position = "dodge", show.legend = T) + 
    scale_fill_grey() + 
    guides(fill = 
     guide_legend(title = "", 
       title.theme = element_text(face = "italic", 
        angle = -0, size = 10))) + 
    theme(legend.text=element_text(size=8)) 


# extract "legends only" from ggplot object 
legend1 <- g_legend(legend1) 
legend2 <- g_legend(legend2) 

# setup legends grid 
legend1_grid <- cowplot::plot_grid(legend1, align = "v", nrow = 2) 

# add second legend to grid, specifying its location 
legends <- legend1_grid + 
    ggplot2::annotation_custom(grob = legend2, 
      xmin = 0.5, xmax = 0.5, ymin = 0.55, ymax = 0.55) 

# plot "plots" + "legends" (with legends in between plots) 
cowplot::plot_grid(plot1, legends, plot2, ncol = 3, 
    rel_widths = c(0.45, 0.1, 0.45)) 

Ví dụ:

Example http://i65.tinypic.com/jl1lef.png

Thay đổi thứ tự của trận chung kết plot_grid() cuộc gọi di chuyển những huyền thoại về bên phải:

cowplot::plot_grid(plot1, plot2, legends, ncol = 3, 
        rel_widths = c(0.45, 0.45, 0.1)) 

Example2 http://i68.tinypic.com/314yn9i.png

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