Search code examples
rsweave

using legend() in Sweave: is this a bug?


Right now I am learning sweave to write a package vignette. I am using traditional R graphics. Strangely a legend that I added to a highlevel plot that works fine otherwise does not work when I Sweave the file. Here is a minimal example:

 \documentclass{article}
 \begin{document}
 <<fig=TRUE>>=
 plot(0.5, 0.5, xlim = c(0,1), ylim = c(0,1))
 legend("bottomright", c("data", "summary", "curve", "conf. region"), 
      pch = c(2,1,NA,NA), lwd = c(NA,NA, 2,1))
 @
 \end{document}

The R code produces (when run R version 2.15) a single point and a legend consisting of two points, and two different types of lines: correct legend

In sweave the legend fails to be produced, I just see an empty box: no legend

Is this a sweave bug, or am I overlooking something?


Solution

  • The problem

    This does appear to be a bug, but it's a problem with pdf() and not with Sweave() itself.

    To see what I mean, try this call to pdf(). It produces the same defective plot displayed above:

    pdf("pdfPlot.pdf")
        plot(0.5, 0.5, xlim = c(0,1), ylim = c(0,1))
        legend("bottomright", c("data", "summary", "curve", "conf. region"), 
             pch = c(2,1,NA,NA), lwd = c(NA,NA, 2,1))
    dev.off()
    

    By contrast, cairo_pdf() produces a plot that looks just fine:

    cairo_pdf("cairo_pdfPlot.pdf")
        plot(0.5, 0.5, xlim = c(0,1), ylim = c(0,1))
        legend("bottomright", c("data", "summary", "curve", "conf. region"), 
             pch = c(2,1,NA,NA), lwd = c(NA,NA, 2,1))
    dev.off()
    

    Solution 1: Use knitr.

    If you are willing to make the switch to knitr, fixing this is easy. Just add dev="cairo_pdf" to your code chunk header (and, if you like, drop the fig=TRUE), like this:

    <<dev="cairo_pdf">>=
    ...
    ...
    @
    

    Processing the code is then as simple as doing library(knitr); knit("myScript.Rnw") in place of your current call to Sweave("myScript.Rnw")

    Solution 2: Construct your own call to \includegraphics{}.

    If you must stick with Sweave(), doing something like this will get you around the problem:

    <<results=tex, term=FALSE, echo=FALSE>>=
    cairo_pdf("myPlot.pdf", width=5)
        plot(0.5, 0.5, xlim = c(0,1), ylim = c(0,1))
        legend("bottomright", c("data", "summary", "curve", "conf. region"),
             pch = c(2,1,NA,NA), lwd = c(NA,NA, 2,1))
    dev.off()
    cat("\\includegraphics{myPlot.pdf}\n\n")
    @