user2054817
user2054817

Reputation: 88

Suppress redraw when calling polygon in R

I would like to draw 60,000+ non-overlapping triangles (part of an unstructured triangular mesh) on a single plot in R. Currently, it takes 15-20 minutes per plot, which makes it impossible to use this for making animations. For example,

n <- 100 #Except replace this with 60,000
x <- matrix(runif(3*n), n)
y <- matrix(runif(3*n), n)
cols <- heat.colors(n)[order(x[,1])]
poly <- function(i) {polygon(x[i,], y[i,], col=cols[i])}
plot(0, xlim=c(min(x),max(x)), ylim=c(min(y),max(y)))
sapply(1:n, poly)

Is it possible to suppress polygon() from redrawing after every polygon? I'm guessing that is the most time consuming step, and it's not mentioned in the man page. Alternative suggestions for how to achieve this would be appreciated. Thank you.

Upvotes: 4

Views: 248

Answers (2)

Ferdinand.kraft
Ferdinand.kraft

Reputation: 12819

You can pass several polygons to polygon. All you have to do is separate then with NA. here's a code:

cuts <- function(x)
{
    n <- length(x) %/% 3

    map <- rep(c(TRUE,TRUE,TRUE,FALSE), n)

    result <- rep(NA, n*4)

    result[map] <- x

    result
}


set.seed(1234)

n <- 10000
x <- matrix(runif(3*n), n)
y <- matrix(runif(3*n), n)
cols <- heat.colors(n)[order(x[,1])]
plot(0, xlim=c(min(x),max(x)), ylim=c(min(y),max(y)))
polygon(x=cuts(t(x)), y=cuts(t(y)), col=cols)

Works fast. I've tested controlling the seed and comparing with the plot generated by your code.

Upvotes: 5

agstudy
agstudy

Reputation: 121578

here a vectorized solution using grid.polygon of the grid package. I use the lattice just to draw the scene( xyplot(0~0) ~ plot(0)).

library(lattice)
library(grid)
xyplot(0~0, xlim=c(min(x),max(x)), ylim=c(min(y),max(y)),
       panel=function(...)
       {
         grid.polygon(x  = as.vector(t(x)),
                      y  = as.vector(t(y)),
                      id = rep(1:n,each=3),
                      gp=gpar(fill=cols),
                      def='native')         
       })

This takes less than 30 seconds in my modest PC to generate the 60000 polygons.

Upvotes: 2

Related Questions