Search code examples
rggplot2knitrr-grid

Why does 2nd ggplot not appear using knitr and grid?


I am trying to create a document using knitr that includes ggplot2 plots modified using grid.

In the example below, there should be 2 plots both using the diamonds dataset included in ggplot2: the first one shows cut vs. color and the second shows cut vs. clarity. Instead, the later plot is repeated twice. The first plot is not generated in the figure directory at all.

\documentclass{article}

\begin{document}

<<fig.cap = c('color', 'clarity')>>=
library(ggplot2)
library(grid)
theme_update(plot.margin = unit(c(1.5, 2, 1, 1), 'lines'))

# Create plot with color

p = ggplot(diamonds,aes(cut,fill = color)) + geom_bar(position = 'fill') + annotate('text', label = as.character(table(diamonds$cut)), x = 1:5, y = Inf, vjust = -1)
gt = ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == 'panel'] = 'off'
grid.draw(gt)

# Create plot with clarity

q = ggplot(diamonds,aes(cut,fill = clarity)) + geom_bar(position = 'fill') + annotate('text', label = as.character(table(diamonds$cut)), x = 1:5, y = Inf, vjust = -1)
gs = ggplot_gtable(ggplot_build(q))
gs$layout$clip[gs$layout$name == 'panel'] = 'off'
grid.draw(gs)
@

\end{document}

Importantly, if I remove the following lines:

gt = ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == 'panel'] = 'off'
grid.draw(gt)

from both figures, then they will both be generated correctly but the annotations will be cut off.

What is causing this issue, and more importantly, how do I fix it?

Thanks!


Solution

  • adding code from comments

    I added a grid.newpage() before the second plot to allow both to render. Also had to tweak the margins to get the annotations to show.

    Sp your code is

    \documentclass{article}
    
    \begin{document}
    
    << fig.cap = c('color', 'clarity')>>=
    library(ggplot2)
    library(grid)
    
    # Create plot with color
    
    p = ggplot(diamonds,aes(cut,fill = color)) + geom_bar(position = 'fill') + annotate('text', label = as.character(table(diamonds$cut)), x = 1:5, y = Inf, vjust = -1) + 
    theme(plot.margin=unit( c(2,1,1,1), "lines") ) ### added
    
    gt = ggplot_gtable(ggplot_build(p))
    gt$layout$clip[gt$layout$name == 'panel'] = 'off'
    grid.draw(gt)
    
    # Create plot with clarity
    
    q = ggplot(diamonds,aes(cut,fill = clarity)) + geom_bar(position = 'fill') + annotate('text', label = as.character(table(diamonds$cut)), x = 1:5, y = Inf, vjust = -1) + 
    theme(plot.margin=unit( c(2,1,1,1), "lines") ) ### added
    
    gs = ggplot_gtable(ggplot_build(q))
    gs$layout$clip[gs$layout$name == 'panel'] = 'off'
    grid.newpage() ## This is the extra line
    grid.draw(gs)
    @
    
    \end{document}