Combine base and ggplot graphics in R figure window

半腔热情 提交于 2019-11-26 00:33:12

问题


I would like to generate a figure that has a combination of base and ggplot graphics. The following code shows my figure using the base plotting functions of R:

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

Which generates \"enter

Most of these panels look sufficient for me to include in my report. However, the plot showing the autocorrelation needs to be improved. This looks much better by using 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

However, seeing as ggplot is not a base graphic, we cannot combine ggplot with layout or par(mfrow). How could I replace the autocorrelation plot generated from the base graphics with the one generated by ggplot? I know I can use grid.arrange if all of my figures were made with ggplot but how do I do this if only one of the plots are generated in ggplot?


回答1:


Using gridBase package, you can do it just by adding 2 lines. I think if you want to do funny plot with the grid you need just to understand and master viewports. It is really the basic object of the grid package.

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

The baseViewports() function returns a list of three grid viewports. I use here figure Viewport A viewport corresponding to the figure region of the current plot.

Here how it looks the final solution:

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



回答2:


You can use the print command with a grob and viewport.
First plot your base graphics then add the 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)



回答3:


I'm a fan of the gridGraphics package. For some reason I had trouble with 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)




回答4:


cowplot package has recordPlot() function for capturing base R plots so that they can be put together in plot_grid() function.

library(biwavelet)
library(ggplot2)
library(cowplot)

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

plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series")
### record the previous plot
p1 <- recordPlot()  

spectrum(y,method = "ar",main = "Spectral density function", 
         xlab = "Frequency (cycles per hour)",ylab = "Spectrum")
p2 <- recordPlot()

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)")
p3 <- recordPlot()

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

### combine all plots together
plot_grid(p1, p4, p2, p3,
          labels = 'AUTO',
          hjust = 0, vjust = 1)

Created on 2019-03-17 by the reprex package (v0.2.1.9000)



来源:https://stackoverflow.com/questions/14124373/combine-base-and-ggplot-graphics-in-r-figure-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!