---
title: "Convert plot to grob and ggplot object"
author: "Guangchuang Yu\\

        School of Basic Medical Sciences, Southern Medical University"
date: "`r Sys.Date()`"
output:
  prettydoc::html_pretty:
    toc: true
    theme: cayman
    highlight: github
  pdf_document:
    toc: true
vignette: >
  %\VignetteIndexEntry{ggplot everything}
  %\VignetteEngine{knitr::rmarkdown}
  %\usepackage[utf8]{inputenc}
---

```{r style, echo=FALSE, results="asis", message=FALSE}
knitr::opts_chunk$set(tidy = FALSE,
		   message = FALSE)
```


```{r echo=FALSE, results="hide", message=FALSE}
library("ggplot2")
library("cowplot")
library("grid")
library("vcd")
library("lattice")
library("colorspace")
library("ggimage")

library("ggplotify")
theme_set(theme_grey())
```


## grid

```{r warning=FALSE}
library("grid")
library("ggplotify")

p1 <- as.grob(~barplot(1:10))
p2 <- as.grob(expression(plot(rnorm(10))))
p3 <- as.grob(function() plot(sin))

library("vcd")
data(Titanic)
p4 <- as.grob(~mosaic(Titanic))

library("lattice")
data(mtcars)
p5 <- as.grob(densityplot(~mpg|cyl, data=mtcars))
```


`as.grob` function accepts plot function call as `expression` or
`formula`, or a function that plots to an R graphics device. The plots can be
generated by base graphics (`p1`, `p2`, `p3`) or `grid` (`p4`). If the plot
function produce graphic object, it can be directly used as input (`p5`,
can be `trellis` object by `lattice` package, `meme` object by `meme` package,
`upset` object by 'UpSetR' package, *etc.*).



It will convert the plot to `grob` object, so that it can be
compatible with `grid` system and related packages.


We can now use `grid.draw` to plot `p1` and `p2`, and use `pushViewport` to
embed plot inside another plot.


```{r fig.width=7, fig.height=7}
grid.newpage()
grid.draw(p1)
vp = viewport(x=.35, y=.75, width=.35, height=.3)
pushViewport(vp)
grid.draw(p2)
upViewport()
```

If you are not family with `grid`, you can use `ggplot2` to do similar task
(*e.g.* `p8` in the below example).

## ggplot2


All the plots that can be converted to `grob` are supported to be converted to
`ggplot` object by using `as.ggplot` function.


```{r warning=FALSE}
library(ggplot2)
p1 <- as.ggplot(~barplot(1:10)) +
    annotate("text", x = .6, y = .5,
             label = "Hello Base Plot", size = 5,
             color = 'firebrick', angle=45)

p2 <- as.ggplot(expression(plot(rnorm(10))))
p3 <- as.ggplot(function() plot(sin))

p4 <- as.ggplot(~mosaic(Titanic))

p5 <- as.ggplot(densityplot(~mpg|cyl, data=mtcars))
```


## Align plots

With all the plots converted to `ggplot` objects, we are able to align plots
produced by 'base' and 'grid' graphic systems using `cowplot` or `patchwork`.


```{r fig.width=14, fig.height=12}
library(cowplot)

library(colorspace)
col <- rainbow_hcl(3)
names(col) <- unique(iris$Species)

color <- col[iris$Species]
p6 <- as.ggplot(~plot(iris$Sepal.Length, iris$Sepal.Width, col=color, pch=15))

p7 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color=Species)) +
    geom_point(shape=15) + scale_color_manual(values=col, name="")

legend <- get_legend(p7)

## also able to annotate base or other plots using ggplot2
library(ggimage)
p8 <- p6 + geom_subview(x=.7, y=.78, subview=legend)


p9 <- as.ggplot(~image(volcano))

plot_grid(p1, p2, p3, p4, p5, p6, p7, p8, p9, ncol=3, labels=LETTERS[1:9])
```
