How to create Animated 3d chart with R.

 


The rgl package is the best option to build 3d charts in R. Please see this post for an introduction to 3d scatterplots using it.

It also provides the plot3d() and play3d() functions that allow to animate the 3d chart, and eventually to export the result at a .gif format. Here is an application to the famous iris dataset, with a nice animated 3d scatterplot chart.

Arguments

x, y, z

vectors of points to be plotted. Any reasonable way of defining the coordinates is acceptable. See the function xyz.coords for details.

xlab, ylab, zlab

labels for the coordinates.

type

For the default method, a single character indicating the type of item to plot. Supported types are: 'p' for points, 's' for spheres, 'l' for lines, 'h' for line segments from z = 0, and 'n' for nothing. For the mesh3d method, one of 'shade', 'wire', or 'dots'. Partial matching is used.

col

the color to be used for plotted items.

size

the size for plotted points.

lwd

the line width for plotted items.

radius

the radius of spheres: see Details below.

add

whether to add the points to an existing plot.

aspect

either a logical indicating whether to adjust the aspect ratio, or a new ratio.

xlim, ylim, zlim

If not NULL, set clipping limits for the plot.

forceClipregion

Force a clipping region to be used, whether or not limits are given.

decorate

Whether to add bounding axes and other decorations.

additional parameters which will be passed to par3dmaterial3d or decorate3d.

Value

plot3d is called for the side effect of drawing the plot; a vector of object IDs is returned.

 

# Let's use the iris dataset
# iris
 
# This is ugly
colors <- c("royalblue1", "darkcyan", "oldlace")
iris$color <- colors[ as.numeric( as.factor(iris$Species) ) ]
 
# Static chart
plot3d( iris[,1], iris[,2], iris[,3], col = iris$color, type = "s", radius = .2 )
 
# We can indicate the axis and the rotation velocity
play3d( spin3d( axis = c(0, 0, 1), rpm = 20), duration = 10 )
 
# Save like gif
movie3d(
  movie="3dAnimatedScatterplot", 
  spin3d( axis = c(0, 0, 1), rpm = 7),
  duration = 10, 
  dir = "~/Desktop",
  type = "gif", 
  clean = TRUE
)

 

 

With the rgl package, you can make the image move and zoom in an out. Find this image in the interactive mode here.

# Library rgl
library(rgl)
 #Choose the size of the image on the output (800,650 to have 800 x 600)
r3dDefaults$windowRect <- c(0,50, 800, 650) 
open3d()
#If you want to put line on the background
#bg3d(sphere = TRUE, color = c("grey", "white"), lit = TRUE, back = "lines" ,lwd=2)
 # This is to output a rgl plot in a rmarkdown document
# rgl::setupKnitr()
  # plot
bg3d( col=rgb(0.2,0.8,0.5,0.8) )
theta <- seq(0, 2*pi, len = 50)
knot <- cylinder3d(
center = cbind(sin(theta) + 3*sin(2*theta), 2*sin(3*theta), cos(theta) - 2*cos(2*theta)),
e1 = cbind(cos(theta) + 4*cos(2*theta),6*cos(3*theta),sin(theta) + 4*sin(2*theta)),radius = 0.9,closed = TRUE)
shade3d(addNormals(subdivision3d(knot, depth = 2)), col = rgb(0.4,0.2,0.8,0.3))
 # To display in an R Markdown document:
# rglwidget()
 # save it as png
# snapshot3d( "~/Desktop/#20_portfolio_knot_3D.png", fmt="png")
 # To save interactive plot to a file:
htmlwidgets::saveWidget(rglwidget(width = 500, height = 500), 
                        file = "HtmlWidget/3dknot.html",
                        libdir = "libs",
                        selfcontained = FALSE
                        )

Animated bubble chart

Before trying to build an animated plot with gganimate, make sure you understood how to build a basic bubble chart with R and ggplot2.

The idea is to add an additional aesthetics called transition_..() that provides a frame variable. For each value of the variable, a step on the chart will be drawn. Here, transition_time() is used since the frame variable is numeric.

Note that the gganimate automatically performs a transition between state. Several options are available, set using the ease_aes() function.

# Get data:

library(gapminder)

 # Charge libraries:

library(ggplot2)

library(gganimate)

 # Make a ggplot, but add frame=year: one image per year

ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, color = continent)) +

  geom_point() +

  scale_x_log10() +

  theme_bw() +

  # gganimate specific bits:

  labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') +

  transition_time(year) +

  ease_aes('linear')

 # Save at gif:

anim_save("271-ggplot2-animated-gif-chart-with-gganimate1.gif")

 

Use small multiple

Since gganimate is a ggplot2 extension, any ggplot2 option can be used to customize the chart. Here, an example using facet_wrap() to use small multiple on the previous chart, spliting the chart window per continent.

# Charge libraries:
library(ggplot2)
library(gganimate)
 # Make a ggplot, but add frame=year: one image per year
ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) +
  geom_point(alpha = 0.7, show.legend = FALSE) +
  scale_colour_manual(values = country_colors) +
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  facet_wrap(~continent) +
  # Here comes the gganimate specific bits
  labs(title = 'Year: {frame_time}', x = 'GDP per capita', y = 'life expectancy') +
  transition_time(year) +
  ease_aes('linear')
 # Save at gif:
anim_save("271-ggplot2-animated-gif-chart-with-gganimate2.gif")

 

Smooth barplot transition


Before trying to build an animated plot with gganimate, make sure you understood how to build a basic bar chart with R and ggplot2.

The idea is to add an additional aesthetics called transition_..() that provides a frame variable. For each value of the variable, a step on the chart will be drawn. Here, transition_states() is used since the frame variable is categorical.

Note that the gganimate automatically performs a transition between state. Several options are available, set using the ease_aes() function.

# libraries:
library(ggplot2)
library(gganimate)
 # Make 2 basic states and concatenate them:
a <- data.frame(group=c("A","B","C"), values=c(3,2,4), frame=rep('a',3))
b <- data.frame(group=c("A","B","C"), values=c(5,3,7), frame=rep('b',3))
data <- rbind(a,b)  
 # Basic barplot:
ggplot(a, aes(x=group, y=values, fill=group)) + 
  geom_bar(stat='identity')
 # Make a ggplot, but add frame=year: one image per year
ggplot(data, aes(x=group, y=values, fill=group)) + 
  geom_bar(stat='identity') +
  theme_bw() +
  # gganimate specific bits:
  transition_states(
    frame,
    transition_length = 2,
    state_length = 1
  ) +
  ease_aes('sine-in-out')
 # Save at gif:
anim_save("288-animated-barplot-transition.gif")

 

 

 

Comments

Popular posts from this blog

Linux/Unix Commands frequently used

R Programming Introduction