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.
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.
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.