2013-01-19 37 views
5

繼最近一個mine的問題後,這一個有點不同,並且使用更簡單的例子更全面地說明了這個問題。以下是兩個數據集和三個功能。第一個按預期繪製一些點和一個圓:ggplot2 0.9.3中的美學繼承和annotation_custom的行爲

library("ggplot2") 
library("grid") 

td1 <- data.frame(x = rnorm(10), y = rnorm(10)) 

tf1 <- function(df) { # works as expected 
    p <- ggplot(aes(x = x, y = y), data = df) 
    p <- p + geom_point(color = "red") 
    p <- p + annotation_custom(circleGrob()) 
    print(p) 
} 

tf1(td1) 

這下一個似乎要求確切的示例圖,但代碼略有不同。它不給一個錯誤,但沒有畫圓:

tf2 <- function(df) { # circle isn't draw, but no error either 
    p <- ggplot() 
    p <- p + geom_point(data = df, aes(x = x, y = y), color = "red")   
    p <- p + annotation_custom(circleGrob()) 
    print(p) 
    } 

tf2(td1) 

最後,這其中涉及到一個更復雜的美感,當你嘗試創建圈子給出了一個空層:

td3 <- data.frame(r = c(rnorm(5, 5, 1.5), rnorm(5, 8, 2)), 
    f1 = c(rep("L", 5), rep("H", 5)), f2 = rep(c("A", "B"), 5)) 

tf3 <- function(df) { 
    p <- ggplot() 
    p <- p + geom_point(data = df, 
     aes(x = f1, y = r, color = f2, group = f2))  
# p <- p + annotation_custom(circleGrob()) # comment out and it works 
    print(p) 
    } 

tf3(td3) 

現在,我懷疑問題這裏不是代碼,但我沒有把握ggplot2的內部工作。 我可以肯定地使用一個解釋爲什麼在第二種情況下沒有繪製圓以及爲什麼在第三種情況下圖層是空的。我看了annotation_custom的代碼,它有一個硬連線inherit.aes = TRUE,我認爲這是問題。我不明白爲什麼這個功能需要任何審美(請參閱它的文檔)。我確實嘗試了幾種方法來覆蓋它,並設置了inherit.aes = FALSE,但我無法完全穿透名稱空間並使其粘住。我試圖舉例說明由ggplot2創建的對象,但這些對象嵌套得非常深,難以破譯。

+0

爲什麼不提交,這個是GitHub的倉庫一個新的問題? – baptiste

+0

@baptiste我在想那個,但是想先把它放在這裏,看看這是我的誤解/不正確的期望,因爲我有這樣的歷史。我會明天提交,除非有人提出解釋(因爲你對這些事情非常瞭解,所以我相信任何人都會)。謝謝。 –

+0

我把這張貼到ggplot2問題跟蹤器。 –

回答

2

要回答這個問題:

「我不明白爲什麼這個函數需要任何美學可言」。

事實上annotation_custom需要x和y AES以擴展其GROB和native單位後使用。 基本上它這樣做:

x_rng <- range(df$x, na.rm = TRUE)       ## ranges of x :aes x 
    y_rng <- range(df$y, na.rm = TRUE)       ## ranges of y :aes y 
    vp <- viewport(x = mean(x_rng), y = mean(y_rng),    ## create a viewport 
       width = diff(x_rng), height = diff(y_rng), 
       just = c("center","center")) 
    dd <- editGrob(grod =circleGrob(), vp = vp)     ##plot the grob in this vp 

爲了說明這一點,我一個GROB添加到作爲我的GROB規模的虛擬情節。第一個是大規模,第二個是小規模。

base.big <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:100,y1=1:100)) 
base.small <- ggplot(aes(x = x1, y = y1), data = data.frame(x1=1:20,y1=1:1)) 

我定義我GROB,看到我用的是原生規模爲XMIN,XMAX,YMIN,YMAX

annot <- annotation_custom(grob = circleGrob(), xmin = 0, 
               xmax = 20, 
               ymin = 0, 
               ymax = 1) 

現在看到的尺度差之間(小點/大圈) (base.big +annot)和(base.small + annot)。

library(gridExtra) 
grid.arrange(base.big+annot, 
      base.small+annot) 

enter image description here

+0

感謝您的回答。我瞭解您編寫的代碼以及它的工作原理,但我不確定它與我的問題之間的關係。我評論不需要審美的原因是該功能不使用審美(從文檔和代碼清楚)。當然,它必須適合vp,但這不是一種審美(問題可能是我沒有正確使用這些術語)。 'annotation_custom'確實使用'inherit.aes'(內部的,而不是參數),但它從哪裏繼承是不清楚的。 –

+0

'x'和'y'具有默認值,這就是您不必傳遞它們的原因。 – baptiste

+0

您寫過「現在看到(base.big + annot)和(base.big + annot)之間的尺度差異(小點/大圓圈)」。我猜你打算寫「(base.small + annot)」。另外,「Bascially」是拼寫錯誤(第三行)。 –