# I made a 3D movie with ggplot2 once – here’s how I did it

August 17, 2017
By

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Some time ago (last year actually ?) I had a blast
developing a feature for `ggforce` which had been on my mind for far to long than
its limited utility warranted. The idea was to showcase the new facetting
extension powers I’d added to `ggplot2` by making a facetting function that
created a stereoscopic pair of plots that would simulate 3D. To procrastinate
and show off I made a little animated video with the feature and posted it on
Twitter, promising I’d write about it someday. Now (again, one year later), I
think the world is finally ready to see what went through my R console to make
that little animation. While I’ve been very timely with this blog post, the
feature is still not available on CRAN, so you’ll need to install the GitHub
version of `ggforce` to follow along.

## Setup

The goal is to create a spinning hollow cube so we’ll need to define the cube
somehow. This was way before `ggraph` was published, and `tidygraph` was not
even a thought in my head, so while it may make sense to handle the cube as a
network, I did it the hard way:

Now that we have our data, we need to create some transformation functions.
Currently, if plotted in `ggplot2` it would just look like a square as,
unsurprisingly, the third dimension would get lost. What we need is a
projection of three dimension down to two. This is a bit hairy, and when I
tried to achieve this back in the days by setting up a transformation matrix
manually I failed miserably (if you are knowledgable in this and want to explain
it to me – please reach out on twitter). In the end I took the shortcut and used
the `persp()` function, which, besides the side effect of plotting stuff in 3D,
also returns the transformation matrix invisibly:

Having a look at the transformation matrix I can safely say that I have no idea
what’s going on:

But that doesn’t matter – the only thing required is that I know how to use it.
The `trans3d()` provides the means for taking in three dimensional points, and a
transformation matrix, and outputting two dimensional points:

With a bit of imagination we can see the 3D cube. Lets draw it with line
segments as well – we add the added information of depth, which is simply the
value in the dimension that gets dropped in the transformation.

We can of course improve the illusion even more. Using `geom_link2()` from
`ggforce`, we can add a gradient size to the lines, based on the depth of the
endpoints (remember, these were added in the `to_grid()` function).

What can we do more? Well, we could decide to rotate it a bit. Let’s, make a
function that rotates it around the vertical axis:

We now have all the ingredients to make an animation of a spinning cube – we
really only need to animate a 90 degree spin as it is selfrepeating. For added
fiz we’ll improve the depth perception by simulating a bit of haze by greying
parts more distant:

That’s all fine and well, but this is just a regular and boring 2D video. Let us
update it to the brave new world, where Avatar has taught us that 3D is not
tacky: Enter `facet_stereo()`.

That is all it takes…

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.