home   >   tutorials   >   3d visualization   >   plotting 3d points (svg)

Plotting 3D points

This tutorial will show you how to plot static and animated 3D points using the R package svgViewR. The uninterrupted block of code can be found at the end of this tutorial.

Preliminary steps

Make sure that you have R installed on your system (you can find R installation instructions here).You will also need to install the latest version of the R package svgViewR on CRAN.

# Install the svgViewR package (if not already installed)
install.packages('svgViewR', dependencies=TRUE)

Creating an interactive visualization of static points

Start by loading the svgViewR package into the current R workspace.

# Load the svgViewR package
library(svgViewR)

Create a distribution of 3D points using the rnorm() function.

# Set number of points to draw
n <- 300

# Create a cloud of normally distributed 3D points
points3d <- cbind(rnorm(n, sd=3), rnorm(n, sd=2), rnorm(n, sd=1))

Open a connection to a new svgViewR .html file. All of the shapes that you draw will be written to this .html file. At the end you'll be able to open this file in a web browser and view the shapes as an interactive graphic.

# Open a connection to .html file
svg.new(file='plot_static_points.html')

To add some color, set each point's color on a color gradient as a function of its distance from the point cloud centroid.

# Get distance of points from the center of point cloud
pdist <- sqrt(rowSums((points3d - matrix(colMeans(points3d), n, 3, byrow=TRUE))^2))

# Set color gradient between red and blue
colfunc <- colorRampPalette(c('red', 'blue'))

# Set desired number of colors along gradient
col_grad <- colfunc(50)

# Scale distances to indices and find corresponding color along gradient
col <- col_grad[(length(col_grad)-1)*(pdist - min(pdist)) / diff(range(pdist))+1]

Add these points to the html file.

# Add points to file
svg.points(points3d, col=col)

Optionally, add a frame around the points. This function outputs the limits of the drawn frame. To surpress this output from being written to the console send the function's output to svg_frame.

# Add coordinate axis planes around the points
svg_frame <- svg.frame(points3d)

Close the connection to the .html file. This adds some closing tags that are needed for the visualization to work properly.

# Close the file connection
svg.close()

You can now open the resulting .html file. It should look something like the image below. Or check out the resulting .html file here.

Plot of static 3D points and bounding coordinate planes.

Note that unlike the base R plotting functions you are not required to specify limits for the plot region prior to plotting shapes. When you open the .html file the javascript code inside the .html file will automatically determine the necessary viewing window dimensions so that all the shapes are visible.

To rotate the graphic click and drag the cursor while holding down the 'r' key or click on the circle arrow icon in the top right corner and then click and drag the cursor. To move the graphic click and drag the cursor or click on the intersecting arrows icon in the top right and click and drag the cursor. To zoom scroll in and out. To return to the initial orientation of the graphic (or to see changes if you re-write the file) refresh the browser.

Creating an interactive visualization of animated points

These 3D points look pretty cool but they would look even cooler if they moved! svgViewR interprets matrices as static shapes and arrays as animated shapes. So to create an animated point cloud all you have to do is specify an array of points. For this example we'll convert the point matrix we made in the previous example into an array.

Start by specifying the number of iterations you'd like in the animation.

# Set number of iterations
n_iter <- 100

Create an 3D point array, filled initially with the previous matrix points. The third dimension of this array represents each of the animation states.

# Create animated point array
points3da <- array(points3d, dim=c(dim(points3d), n_iter))

To create an easy animation we'll simply multiple the xyz-coordinates at each iteration by the square of the iteration, starting with 0. This will cause the points to expand at an accelerating rate from the origin. Scaling the coordinates down by 0.001 keeps the axis labels between 0 and 100.

# Expand points from origin
for(iter in 0:(n_iter-1)){
	points3da[, , iter] <- points3da[, , iter] * 0.001 * iter^2
}

You're ready to plot the animated points. These can be plotted in the exact same way as the static points, simply replace points3d with points3da.

# Open a connection to .html file
svg.new(file='plot_animated_points.html')

# Add points to file
svg.points(points3da, col=col)

# Add coordinate axis planes around the points
svg_frame <- svg.frame(points3da)

# Close the file connection
svg.close()

Open 'plot_animated_points.html' and you should now have an interactive animation like here or like in the video below.

Plot of animated 3D points and bounding coordinate planes.

Uninterrupted code


# Load the svgViewR package
library(svgViewR)

# Set number of points to draw
n <- 300

# Create a cloud of normally distributed 3D points
points3d <- cbind(rnorm(n, sd=3), rnorm(n, sd=2), rnorm(n, sd=1))

# Open a connection to .html file
svg.new(file='plot_static_points.html')

# Get distance of points from the center of point cloud
pdist <- sqrt(rowSums((points3d - matrix(colMeans(points3d), n, 3, byrow=TRUE))^2))

# Set color gradient between red and blue
colfunc <- colorRampPalette(c('red', 'blue'))

# Set desired number of colors along gradient
col_grad <- colfunc(50)

# Scale distances to indices and find corresponding color along gradient
col <- col_grad[(length(col_grad)-1)*(pdist - min(pdist)) / diff(range(pdist))+1]

# Add points to file
svg.points(points3d, col=col)

# Add coordinate axis planes around the points
svg_frame <- svg.frame(points3d)

# Close the file connection
svg.close()

# Set number of iterations
n_iter <- 100

# Create animated point array
points3da <- array(points3d, dim=c(dim(points3d), n_iter))

# Expand points from origin
for(iter in 0:(n_iter-1)){
	points3da[, , iter] <- points3da[, , iter] * 0.001 * iter^2
}

# Open a connection to .html file
svg.new(file='plot_animated_points.html')

# Add points to file
svg.points(points3da, col=col)

# Add coordinate axis planes around the points
svg_frame <- svg.frame(points3da)

# Close the file connection
svg.close()