开发者

Multipage SVG with R

When using layout in lattice::xyplot with trellis.device you can get several pages in a PDF:

trellis.device(pdf, file="myfile.pdf")
data(mtcars)
xyplot(hp~mpg|gear, data=mtcars, l开发者_Python百科ayout=c(1, 1))
dev.off()

I would like to use the same approach to get a multi-page SVG. I have tried cairo::svg, and the packages gridSVG, SVGAnnotation and RSVGTipsDevice with no success: only the last page of the trellis object is saved.

Is there any solution using R code?

Thanks!


I finally decided to ask directy to Paul Murrell, the creator of grid and gridSVG. He kindly provided some good advices and code which completely solved the problem with an approach similar to the advice from @mbq. I modified his code to write this function:

library(gridSVG)
library(XML)

animateTrellis <- function(object, file='animatedSVG.svg', 
                           duration=.1, step=2, show=TRUE){
  nLayers <- dim(object)
  stopifnot(nLayers>1)
  for (i in seq_len(nLayers)){
    p <- object[i]
    label <- p$condlevels[[1]][i]
    ##Create intermediate SVG files
    g <- grid.grabExpr(print(p, prefix=label),
                       name=label)
    if (i==1){ ## First frame
      ga <- animateGrob(g, group=TRUE,
                        visibility="hidden",
                        duration=duration, begin=step)
    } else if (i==nLayers){ ##Last Frame
      gg <- garnishGrob(g, visibility='hidden')
      ga <- animateGrob(gg, group=TRUE,
                        visibility="visible",
                        duration=duration, begin=step*(i-1))
    } else { ##any frame
      gg <- garnishGrob(g, visibility='hidden')
      gaV <- animateGrob(gg, group=TRUE,
                         visibility="visible",
                         duration=duration, begin=step*(i-1))
      ga <- animateGrob(gaV, group=TRUE,
                        visibility="hidden",
                        duration=duration, begin=step*i)
    }
    grid.newpage()
    grid.draw(ga)
    fich <- tempfile(fileext='.svg')
    gridToSVG(fich)

    ## Combine all
    if (i==1) {
      svgTop <- xmlParse(fich)
      nodeTop <- getNodeSet(svgTop,
                            "//svg:g[@id='gridSVG']",
                            c(svg="http://www.w3.org/2000/svg"))[[1]]
    } else {
      svgChildren <- xmlParse(fich)
      node <- getNodeSet(svgChildren,
                         "//svg:g[@id='gridSVG']/*",
                         c(svg="http://www.w3.org/2000/svg"))
      addChildren(nodeTop, node)
    }
    unlink(fich)
  }
  saveXML(svgTop, file=file)
  dev.off()
  if (show) browseURL(file)
  invisible(svgTop)
}

Then I can produce the SVG file with animation:

p <- xyplot(Sepal.Length~Petal.Length|Species, data=iris, layout=c(1, 1))
animateTrellis(p, file='iris.svg')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜