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
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()
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?
Combine multiple ggplots using ggarrange() the line plot (lp) will live in the first row and spans over two columns. the box plot (bxp) and the dot plot (dp) will be first arranged and will live in the second row with two different columns.
In Matplotlib, we can draw multiple graphs in a single plot in two ways. One is by using subplot() function and other by superimposition of second graph on the first i.e, all graphs will appear on the same plot.
Base R plots two vectors as x and y axes and allows modifications to that representation of data whereas ggplot2 derives graphics directly from the dataset. This allows faster fine-tuning of visualizations of data rather than representations of data stitched together in the Base R package1.
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) library(grid) 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With