Rev 81097 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
library(grid)HersheyLabel <- function(x, y=unit(.5, "npc")) {lines <- strsplit(x, "\n")[[1]]if (!is.unit(y))y <- unit(y, "npc")n <- length(lines)if (n > 1) {y <- y + unit(rev(seq(n)) - mean(seq(n)), "lines")}grid.text(lines, y=y, gp=gpar(fontfamily="HersheySans"))}################################################################################## Enforce a clipping path on a viewportgrid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))HersheyLabel("push circle clipping pathrectgrey circle")## NORMAL clipping(!)grid.newpage()pushViewport(viewport(width=.5, height=.5, clip=TRUE))grid.circle(r=.6, gp=gpar(fill="grey"))HersheyLabel("push clipping rectcirclesquared circle")## A slightly more complex clipping pathgrid.newpage()pushViewport(viewport(clip=circleGrob(1:2/3, r=unit(.5, "in"))))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("push two circles clipping pathrecttwo circles")## Clip to a polygongrid.newpage()pushViewport(viewport(width=.5, height=.5,clip=polygonGrob(c(.2, .4, .6, .2), c(.2, .6, .4, .1))))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("push clipping pathrectgrey wedge")## Rotated clip rect!grid.newpage()pushViewport(viewport(width=.5, height=.6, angle=45, clip=rectGrob()))grid.circle(r=.6, gp=gpar(fill="grey"))HersheyLabel("push rotated viewportwith clipping pathcirclesquare-sided circle")## Clipping gradient output## (gradient on viewport)grid.newpage()pushViewport(viewport(clip=circleGrob(1:2/3, r=unit(.5, "in")),gp=gpar(fill=linearGradient())))grid.rect()popViewport()HersheyLabel("push clipping pathgradient on viewporttwo circles (one gradient)")## Clipping gradient output## (gradient on grob)grid.newpage()pushViewport(viewport(clip=circleGrob(1:2/3, r=unit(.5, "in"))))grid.rect(gp=gpar(fill=linearGradient()))popViewport()HersheyLabel("push clipping pathrect with gradienttwo circles (one gradient)")## Inheriting clipping paths (between viewports)grid.newpage()pushViewport(viewport(clip=circleGrob()))pushViewport(viewport())grid.rect(gp=gpar(fill="grey"))HersheyLabel("push clipping pathpush again (inherit clip path)rectgrey circle")## Restoring clipping paths (between viewports)grid.newpage()pushViewport(viewport(clip=circleGrob()))pushViewport(viewport())pushViewport(viewport())upViewport()grid.rect(gp=gpar(fill="grey"))HersheyLabel("push clipping pathpush again (inherit clip path)push again (inherit clip path)up (restore inherited clip path)rectgrey circle")## Revisiting clipping on a viewport## upViewport()grid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))upViewport()grid.rect(gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clipping pathgrey circleupViewportpage all (translucent) blue")## downViewport()grid.newpage()pushViewport(viewport(clip=circleGrob(), name="vp"))grid.rect(height=.5, gp=gpar(fill="grey"))upViewport()downViewport("vp")grid.rect(gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clipping pathrounded rectupViewportdownViewportblue (translucent) circle")## clip rect to clip path back to clip rectgrid.newpage()pushViewport(viewport(width=.5, height=.5, clip=TRUE))pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))upViewport()grid.circle(r=.6, gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clipping rectpush clipping pathgrey circleupViewportsquared (translucent) blue circle")## clip path to clip rect back to clip pathgrid.newpage()pushViewport(viewport(clip=circleGrob()))pushViewport(viewport(width=.5, height=.5, clip=TRUE))grid.circle(r=.6, gp=gpar(fill="grey"))upViewport()grid.rect(gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clipping pathpush clipping rectsquared circleupViewportgrey (translucent) blue circle")## Clipping path makes the clipping region BIGGERgrid.newpage()pushViewport(viewport(width=.5, height=.5, clip=TRUE))grid.rect()pushViewport(viewport(clip=circleGrob(r=.6)))grid.rect(width=1.2, height=1.2, gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clip rect (small)rectpush clip path (bigger)rect (big)blue (translucent) circle")## Clipping path makes the clipping region BIGGER## (even when clipping path contains viewport)grid.newpage()pushViewport(viewport(width=.5, height=.5, clip=TRUE))grid.rect()pushViewport(viewport(clip=circleGrob(r=.6, vp=viewport())))grid.rect(width=1.2, height=1.2, gp=gpar(fill=rgb(0,0,1,.2)))HersheyLabel("push clip rect (small)rectpush clip path with viewport (bigger)rect (big)blue (translucent) circle")######################################## Replaying the graphics display list## Resizing devicegrid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))HersheyLabel("push clip pathrectgrey circle(for resizing)")## Record and replaygrid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))x <- recordPlot()HersheyLabel("push clip pathrectgrey circle(for recording)")print(x)HersheyLabel("push clip pathrectrecord plotreplay plotgrey circle")######################################## Test of 'grid' display list## Grabbing a grob with clipping## (replaying the 'grid' display list)grid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))HersheyLabel("push clip pathrectgrey circle(for grid.grab)")x <- grid.grab()grid.newpage()grid.draw(x)HersheyLabel("push clip pathrectgrey circlegrid.grabgrid.drawgrey circle")######################## Check for outlawed behaviour## (clipping and masks are turned off during clipping path resolution)grid.newpage()path <- circleGrob(r=.6,vp=viewport(width=.5, height=.5, clip=TRUE))pushViewport(viewport(clip=path))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("clipping path is circle with viewport with clip=TRUEAND circle is larger than viewportBUT viewport clipping is ignored within clipping pathSO clipping path is just circledraw rectresult is grey circle")grid.newpage()path <- circleGrob(vp=viewport(clip=rectGrob(width=.8, height=.8)))pushViewport(viewport(clip=path))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("clip path is circle with viewport with clip pathviewport clip path is rect that squares off the circleBUT clip paths are ignored within clipping path (with warning)SO clipping path is just circledraw rectresult is grey circle")grid.newpage()path <- circleGrob(vp=viewport(mask=rectGrob(width=.8, height=.8,gp=gpar(fill="black"))))pushViewport(viewport(clip=path))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("clip path is circle with viewport with maskviewport mask is rect that squares off the circleBUT masks are ignored within clipping path (with warning)SO clipping path is just circledraw rectresult is grey circle")grid.newpage()path <- circleGrob(vp=viewport(mask=rectGrob(width=.8, height=.8,gp=gpar(fill="black"))))pushViewport(viewport(clip=path, name="test"))upViewport()downViewport("test")grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("same as previous testEXCEPT that push viewport then pop then down(and only push should warn)draw rectresult is grey circle")## A clipping path within a makeContent() methodgrid.newpage()g <- gTree(cl="test")makeContent.test <- function(x) {setChildren(x, gList(rectGrob(gp=gpar(fill="grey"),vp=viewport(clip=circleGrob()))))}grid.draw(g)HersheyLabel("custom grob class with makeContent() methodmakeContent() adds rectangle with viewportviewport has circle clip pathresult is grey circle")## A clipping path that makes use of makeContent() methodgrid.newpage()path <- gTree(cl="test")makeContent.test <- function(x) {setChildren(x, gList(circleGrob()))}pushViewport(viewport(clip=path))grid.rect(gp=gpar(fill="grey"))popViewport()HersheyLabel("push viewport with clip pathclip path is grob with makeContent() methodmakeContent() adds circledraw rectresult is grey circle")## save()/load() a recordedPlot containing a clipping pathgrid.newpage()pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))x <- recordPlot()HersheyLabel("push circle clipping pathrectgrey circle(for save(recordPlot()))")f <- tempfile()saveRDS(x, file=f)grid.newpage()y <- readRDS(f)replayPlot(y)HersheyLabel("push circle clipping pathrectgrey circlesaveRDS(recordPlot())replayPlot(readRDS())")################################################################################## Clipping paths from textgrid.newpage()tg <- textGrob("testing", gp=gpar(fontface="bold", cex=4))pushViewport(viewport(clip=tg))grid.rect(gp=gpar(fill="grey"))grid.rect(width=.1, gp=gpar(fill="2"))popViewport()HersheyLabel("clipping path from textgrey rect clipped to textthin red rect (black border) also clipped to text", y=.9)grid.newpage()gt <- gTree(children=gList(circleGrob(),textGrob("testing", gp=gpar(fontface="bold", cex=4)),rectGrob(width=.8, height=.5)))pushViewport(viewport(clip=as.path(gt, rule="evenodd")))grid.rect(gp=gpar(fill="grey"))grid.rect(width=.1, gp=gpar(fill="2"))popViewport()HersheyLabel("clipping path based on circle and text and rectwith even-odd ruledraw large grey rect and thin red rectboth clipped to text and space between circle and rect(PDF will NOT include text in clipping path", y=.85)grid.newpage()gt <- gTree(children=gList(textGrob("testing", gp=gpar(fontface="bold", cex=4)),circleGrob(),rectGrob(width=.8, height=.5)))pushViewport(viewport(clip=as.path(gt, rule="evenodd")))grid.rect(gp=gpar(fill="grey"))grid.rect(width=.1, gp=gpar(fill="2"))popViewport()HersheyLabel("clipping path based on text and circle and rectwith even-odd ruledraw large grey rect and thin red rectboth clipped to text and space between circle and rect(PDF will ONLY include text in clipping path", y=.85)######################## Check resource exhaustiongrid.newpage()for (i in 1:65) {pushViewport(viewport(clip=circleGrob()))grid.rect(gp=gpar(fill="grey"))HersheyLabel(paste0("viewport ", i, " with clip pathresult is grey circle"))upViewport()}## Text being clipped by pathgrid.newpage()grid.text("testing", gp=gpar(col="grey", cex=3))path <- circleGrob(r=.05, gp=gpar(fill=NA))grid.draw(path)pushViewport(viewport(clip=path))grid.text("testing", gp=gpar(cex=3))popViewport()HersheyLabel("text clipped by circle", y=.8)## Raster being clipped by pathgrid.newpage()grid.raster(matrix(c(.5, 1, 1, .5), nrow=2),width=.2, height=.2,interpolate=FALSE)path <- circleGrob(r=.05, gp=gpar(fill=NA))grid.draw(path)pushViewport(viewport(clip=path))grid.raster(matrix(c(0:1, 1:0), nrow=2),width=.2, height=.2,interpolate=FALSE)popViewport()HersheyLabel("raster clipped by circle", y=.8)