A while ago, I wanted to produce a figure for a presentation about spatial organization. I decided to use R for the task. I had two objectives: 1) display a grid representing a concave surface (something akin to a half-pipe ramp in skateboarding) and 2) each “cell” of the grid was to be colored in 2 different ways: either randomly (no organization) or organized along the major axis of the concave surface (ie. colors mirrored each other on either “side” of the half-pipe ramp). If you’re confused, the final graphics are at the bottom. After some fits and starts, I used persp() function along with an simple exponential function to get the curvature I wanted. Enjoy, and let me know what you think!

### Random pattern # Create matrix with random values with dimension of final grid rand <- rnorm(441, mean=0.3, sd=0.1) mat.rand <- matrix(rand, nrow=21) # Create another matrix for the colors. Start by making all cells green fill <- matrix("green3", nr = 21, nc = 21) # Change colors in each cell based on corresponding mat.rand value fcol <- fill fcol[] <- terrain.colors(40)[cut(mat.rand, stats::quantile(mat.rand, seq(0,1, len = 41), na.rm=T), include.lowest = TRUE)] # Create concave surface using expontential function x <- -10:10 y <- x^2 y <- as.matrix(y) y1 <- y for(i in 1:20){tmp <- cbind(y,y1); y1 <- tmp[,1]; y <- tmp;} mat <- tmp[1:21, 1:21] # Plot it up! persp(1:21, 1:21, t(mat)/10, theta = 90, phi = 35,col=fcol, scale = FALSE, axes = FALSE, box = FALSE)

Now for the organized pattern. Slightly more tricky…

### Organized pattern # Same as before rand <- rnorm(441, mean=0.3, sd=0.1) # Create concave surface using expontential function x <- -10:10 y <- x^2 y <- as.matrix(y) for(i in 1:20){tmp <- cbind(y,y); y1 <- tmp[,1]; y <- tmp;} mat <- tmp[1:21, 1:21] ###Organize rand by y and put into matrix form o <- order(rand,as.vector(mat)) o.tmp <- cbind(rand[o], rev(sort(as.vector(mat)))) mat.org <- matrix(o.tmp[,1], nrow=21) half.1 <- mat.org[,seq(1,21,2)] half.2 <- mat.org[,rev(seq(2,20,2))] full <- cbind(half.1, half.2) full <- t(full) # Again, create color matrix and populate using rand values zi <- full[-1, -1] + full[-1, -21] + full[-21,-1] + full[-21, -21] fill <- matrix("green3", nr = 20, nc = 20) fcol <- fill fcol[] <- terrain.colors(40)[cut(zi, stats::quantile(zi, seq(0,1, len = 41), na.rm=T), include.lowest = TRUE)] # Plot it up! persp(1:21, 1:21, t(mat)/10, theta = 90, phi = 35,col=t(fcol), scale = FALSE, axes = FALSE, box = FALSE)