2013-01-02 66 views
59

我想生成一個包含base和ggplot圖形組合的圖形。下面的代碼顯示了使用基礎繪製的R功能我的身影:在R圖窗口中合併base和ggplot圖形

t <- c(1:(24*14)) 
P <- 24 
A <- 10 
y <- A*sin(2*pi*t/P)+20 

par(mfrow=c(2,2)) 
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series") 
acf(y,main = "Autocorrelation",xlab = "Lag (hours)", ylab = "ACF") 
spectrum(y,method = "ar",main = "Spectral density function", 
     xlab = "Frequency (cycles per hour)",ylab = "Spectrum") 
require(biwavelet) 
t1 <- cbind(t, y) 
wt.t1=wt(t1) 
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform", 
    ylab = "Period (hours)",xlab = "Time (hours)") 

產生 enter image description here

大多數面板看起來夠我在我的報表中。但是,顯示自相關的情節需要改進。這看起來使用ggplot好得多:

require(ggplot2) 
acz <- acf(y, plot=F) 
acd <- data.frame(lag=acz$lag, acf=acz$acf) 
ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") + 
    geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") + 
    theme_bw() 

enter image description here

然而,看到ggplot不是將基本圖形,我們不能與佈局或參數(mfrow)結合ggplot。我怎樣才能將由基礎圖形生成的自相關圖替換爲由ggplot生成的自相關圖?我知道我可以使用grid.arrange,如果我的所有數字都是用ggplot製作的,但是如果只有其中一個圖形在ggplot中生成,我該如何做到這一點?

+3

它可能是幾乎一樣簡單,而且看起來更一致,使用'polygon'與ACF的'輸出()'來構建類似於'ggplot'基本圖形情節一。 –

+0

感謝您的回覆。這個問題的目的在於學習如何在數字窗口中結合ggplot和基礎圖形,我意識到可能有更有效的方式來生成所示的圖形,但爲了將來的目的,我想了解指定的方法。 – KatyB

+3

查看'gridBase'軟件包... –

回答

47

使用gridBase包,只需添加2行即可。我想如果你想用網格做有趣的陰謀,你只需要瞭解並掌握視口。它確實是網格包的基本對象。

vps <- baseViewports() 
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot 

baseViewports()函數返回三個網格視口的列表。我在這裏使用圖視口 對應於當前圖的圖區域的視口。

呢?這裏怎麼看起來最終的解決方案:

enter image description here

library(gridBase) 
par(mfrow=c(2, 2)) 
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series") 
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform", 
    ylab = "Period (hours)",xlab = "Time (hours)") 
spectrum(y,method = "ar",main = "Spectral density function", 
     xlab = "Frequency (cycles per hour)",ylab = "Spectrum") 
## the last one is the current plot 
plot.new()    ## suggested by @Josh 
vps <- baseViewports() 
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot 
vp1 <-plotViewport(c(1.8,1,0,1)) ## create new vp with margins, you play with this values 
require(ggplot2) 
acz <- acf(y, plot=F) 
acd <- data.frame(lag=acz$lag, acf=acz$acf) 
p <- ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") + 
    geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") + 
    theme_bw()+labs(title= "Autocorrelation\n")+ 
    ## some setting in the title to get something near to the other plots 
    theme(plot.title = element_text(size = rel(1.4),face ='bold')) 
print(p,vp = vp1)  ## suggested by @bpatiste 
+0

是的,我已經試過這個,這個問題是用ggplot生成的情節要大得多比其他小組(如你所見)。有沒有改變這種方法? – KatyB

+0

@Kate我上傳了我的答案。 – agstudy

+0

+1非常好。如果您通過調用「plot」將呼叫替換爲'acf(...)',new()',你可以避免不得不調用'grid.rect()'來「清空」acf圖。 –

10

您可以使用打印命令與格羅和視口。
首先情節你的基礎圖形,然後添加ggplot

library(grid) 

# Let's say that P is your plot 
P <- ggplot(acd, # etc...) 

# create an apporpriate viewport. Modify the dimensions and coordinates as needed 
vp.BottomRight <- viewport(height=unit(.5, "npc"), width=unit(0.5, "npc"), 
          just=c("left","top"), 
          y=0.5, x=0.5) 

# plot your base graphics 
par(mfrow=c(2,2)) 
plot(y,type #etc ....) 

# plot the ggplot using the print command 
print(P, vp=vp.BottomRight) 
+0

裏卡多你好。你知道如何用你的方法來控制地塊的寬度嗎?例如,我想要一個基本圖形和一個ggplot2圖形並排放置,但基本圖形的寬度較大。 –

+0

嗨Stéphane,你可以完成這個調整'viewport()'行中的設置。具體而言,您需要調整'width'和'y'值,嘗試使用不同的值直到獲得所需的結果。 –

+0

謝謝里卡多。其實我在這裏打開一個問題http://stackoverflow.com/questions/14358526/controlling-column-widths-for-side-by-side-base-graphic-and-ggplot2-graphic/14358752 –

5

我是gridGraphics包的粉絲。由於某種原因,我遇到了gridBase問題。

library(ggplot2) 
library(gridGraphics) 
data.frame(x = 2:10, y = 12:20) -> dat 
plot(dat$x, dat$y) 
grid.echo() 
grid.grab() -> mapgrob 
ggplot(data = dat) + geom_point(aes(x = x, y = y)) 
pushViewport(viewport(x = .8, y = .4, height = .2, width = .2))  
grid.draw(mapgrob) 

enter image description here