Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knitr: calling a ggplot2 function in a loop doesn't plot when accompanied by certain other plotting functions

Tags:

r

ggplot2

knitr

I'm not sure if this is a true bug or I'm missing something, but here it goes. I have a ggplot function (plot_data) that I'd like to call in a loop. I've included the function in its own chunk. Calling the function works fine in a loop in case one (the chunk titled "works"), in this case the plot_data function is followed by a barplot. However, in the second case, the plot_data() function is followed by a heatmap in which case, but the heatmap, oddly, suppresses the plot_data function. This happens whether or not plot() or print() is called around the plot_data function.

Is there a way to get ggplots to behave with knitr? And how in the hell is a function call suppressing the output of a previous function call?

The following code reproduces the error for me:

[preamble omitted]
\begin{document}

<<setup, eval=TRUE, echo=FALSE, cache=FALSE>>=
plot_data <- function(data) {
    require(ggplot2)
    require(reshape)
    d.melt <- melt(data)
    ggplot(data=d.melt, aes(x=X2, y=value, group=X1, colour=X1)) + geom_line(size=.5) +
          scale_x_discrete("") +
          scale_y_continuous("Value")
    }
@

<<works, echo=FALSE, results='asis', out.width='.3\\linewidth', dev='pdf', cache=TRUE >>=
set.seed(10010)
data <- matrix(runif(10000, 1,100), ncol=100)
for (i in 1:10) {
    ind <- sample(1:100, 10)
    plot(plot_data(data[ind,]))
    barplot(ind)
}
@

<<doesnt-work, echo=FALSE, results='asis', out.width='.3\\linewidth', dev='pdf', cache=TRUE >>=
set.seed(10010)
data <- matrix(runif(10000, 1,100), ncol=100)
for (i in 1:10) {
    ind <- sample(1:100, 10)
    plot(plot_data(data[ind,]))  # calling print instead of plot doesn't work either
    heatmap(data[ind,]  )
}
@

\end{document}
like image 241
zzk Avatar asked Mar 19 '13 03:03

zzk


1 Answers

I think you ask a lot from knitr. Aligning base graphics and grid graphics is not very easy and challenging in R. I don't know how knitr do it maybe using (package latex graphics), but what I think is when you call the heatmap , it is print in the same place of the grid plot.

Adding a plot.new before calling the base graphics works fine for me:

<<doesnt-work, fig.show='hold',out.width='.3\\linewidth'>>=
  set.seed(10010)
data <- matrix(runif(10000, 1,100), ncol=100)
for (i in 1:3) {
  ind <- sample(1:100, 10)
  print(plot_data(data[ind,]))  # calling print instead of plot doesn't work either
  plot.new()
  heatmap(data[ind,]  )
 }
@
like image 144
agstudy Avatar answered Oct 20 '22 21:10

agstudy