Daniel G
Daniel G

Reputation: 153

grid: Grid graphics flickering

I'm designing an interactive plot using the grid package in R. As part of the interactivity, I repeatedly delete and re-create various parts of the plot. However, the total number of grid elements (as obtained using the grid.ls() command) stays constant; everything I create was previously removed.

The problem is as follows - once I've gone through a few cycles of creation and deletion, every deletion I make to the graphic, however small, causes all the interactive parts of the plot (those I've been repeatedly deleting and creating) to flicker.

Here's the simplest example I could come up with - first run this code to set up the grid graphic, and repeatedly delete and re-create certain elements

library(grid)

pushViewport(viewport())

for (x in seq(0, 1, length=5))
{
    for (y in seq(0, 1, length=5))
    {
        pushViewport(viewport(x = x, y = y, width=1/5, height=1/5, name=paste("foo", x, y, sep="")))
        grid.rect()

        pushViewport(viewport(x = 0, 0, width=1/4, height=1/4, name="bar1"))
        grid.circle(name="testing")
        grid.text("123")
        upViewport()

        pushViewport(viewport(x = 1, 0, width=1/4, height=1/4, name="bar2"))
        grid.circle(name="testing")
        grid.text("123")
        upViewport()

        pushViewport(viewport(x = 0, 1, width=1/4, height=1/4, name="bar3"))
        grid.circle(name="testing")
        grid.text("123")
        upViewport()

        pushViewport(viewport(x = 1, 1, width=1/4, height=1/4, name="bar4"))
        grid.circle(name="testing")
        grid.text("123")
        upViewport()

        upViewport()
    }
}

for (i in 1:10)
{

    grid.gremove("testing")

    for (x in seq(0, 1, length=5))
    {
        for (y in seq(0, 1, length=5))
        {
            downViewport(paste("foo", x, y, sep=""))

            downViewport("bar1"); grid.circle(name="testing"); upViewport()
            downViewport("bar2"); grid.circle(name="testing"); upViewport()
            downViewport("bar3"); grid.circle(name="testing"); upViewport()
            downViewport("bar4"); grid.circle(name="testing"); upViewport()

            upViewport()
        }
    }

}

Once this is all set up, create a new arbitrary square on the device

grid.rect(height=0.5, width=0.5, gp=gpar(lty = 2), name = "lastShape")

Now try to delete it

grid.gremove("lastShape")

Notice that when you run this last deletion command, all the small circles that I've been creating and deleting flicker slightly, even though I haven't touched them. This makes the entire graphic very distracting.

Any ideas how to prevent that?

Thanks a million!

Upvotes: 5

Views: 476

Answers (1)

Daniel G
Daniel G

Reputation: 153

@hadley - you da boss! Your first comment provided the correct answer; I'm copying it and expanding it here for future reference...

All you need to do is use

dev.hold()

# .... do scary modifications ...

dev.flush()

Seems to work a treat. I'll re-post if it breaks again.

Note: This is only available in R v3 onwards...

Upvotes: 5

Related Questions