Trisurf Plots in R using Plotly
[This article was first published on R – Modern Data, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
In this post we’ll show how to create Triangular Surface Plots in R. This post is based on timelyportfolio’s gist.
Moebius Strip
library(plotly) library(geometry) g <- expand.grid( u = seq(0, 2 * pi, length.out = 24), v = seq(-1, 1, length.out = 8) ) tp <- 1 + 0.5 * g$v * cos(g$u / 2) m <- matrix( c(tp * cos(g$u), tp * sin(g$u), 0.5 * g$v * sin(g$u / 2)), ncol = 3, dimnames = list(NULL, c("x", "y", "z")) ) # the key though is running delaunayn on g rather than m d <- delaunayn(g) td <- t(d) # but using m for plotting rather than the 2d g # define layout options axs <- list( backgroundcolor="rgb(230,230,230)", gridcolor="rgb(255,255,255)", showbackground=TRUE, zerolinecolor="rgb(255,255,255" ) # now figure out the colormap # start by determining the mean of z for each row # of the Delaunay vertices zmean <- apply(d, MARGIN=1, function(row){mean(m[row,3])}) library(scales) # result will be slighlty different # since colour_ramp uses CIELAB instead of RGB # could use colorRamp for exact replication facecolor = colour_ramp( brewer_pal(palette="RdBu")(9) )(rescale(x=zmean)) plot_ly( x = m[, 1], y = m[, 2], z = m[, 3], # JavaScript is 0 based index so subtract 1 i = d[, 1]-1, j = d[, 2]-1, k = d[, 3]-1, facecolor = facecolor, type = "mesh3d" ) %>% layout( title="Moebius band triangulation", scene=list(xaxis=axs,yaxis=axs,zaxis=axs), aspectratio=list(x=1,y=1,z=0.5) )
2D Surface over a disk
n <- 12 h <- 1/(n-1) r = seq(h, 1, length.out=n) theta = seq(0, 2*pi, length.out=36) g <- expand.grid(r=r, theta=theta) x <- c(g$r * cos(g$theta),0) y <- c(g$r * sin(g$theta),0) z <- sin(x*y) m <- matrix( c(x,y,z), ncol = 3, dimnames = list(NULL, c("x", "y", "z")) ) tri <- delaunayn(m[,1:2]) # now figure out the colormap zmean <- apply(tri,MARGIN=1,function(row){mean(m[row,3])}) library(scales) library(rje) facecolor = colour_ramp( cubeHelix(12) )(rescale(x=zmean)) plot_ly( x=x, y=y, z=z, i=tri[,1]-1, j=tri[,2]-1, k=tri[,3]-1, facecolor=facecolor, type="mesh3d" ) %>% layout( title="Triangulated surface", scene=list( xaxis=axs, yaxis=axs, zaxis=axs, camera=list( eye=list(x=1.75,y=-0.7,z=0.75) ) ), aspectratio=list(x=1,y=1,z=0.5) )
Chopper from python
library(geomorph) plyFile <- 'http://people.sc.fsu.edu/~jburkardt/data/ply/chopper.ply' dest <- basename(plyFile) if (!file.exists(dest)) { download.file(plyFile, dest) } mesh <- read.ply(dest) # see getS3method("shade3d", "mesh3d") for details on how to plot # plot point cloud x <- mesh$vb["xpts",] y <- mesh$vb["ypts",] z <- mesh$vb["zpts",] m <- matrix(c(x,y,z), ncol=3, dimnames=list(NULL,c("x","y","z"))) # now figure out the colormap zmean <- apply(t(mesh$it),MARGIN=1,function(row){mean(m[row,3])}) library(scales) facecolor = colour_ramp( brewer_pal(palette="RdBu")(9) )(rescale(x=zmean)) plot_ly( x = x, y = y, z = z, i = mesh$it[1,]-1, j = mesh$it[2,]-1, k = mesh$it[3,]-1, facecolor = facecolor, type = "mesh3d" )
To leave a comment for the author, please follow the link and comment on their blog: R – Modern Data.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.