The MakeR way: Using R to reify social media data via 3d printing
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
If you’ve read any of my previous posts you know that I am constantly experimenting with different ways to represent and explore social network data with R. For example, in previous posts I’ve written about sonification of tweet data, animation of dynamic twitter networks, and various ways to plot social networks (here and here). In each case the underlying idea is finding different ways to explore data under the assumption that sometimes just looking at something from a different point of view reveals something novel. In this post I will briefly discuss how to go from data to 3D model network, to 3D object using R most of the way.
First, why would anyone want to take network data, model it in 3D and then use a 3D printer to make it real? What is the advantage of representing data in such a way that you can hold it in your hand? I think there are many answers to this question, but as an illustration I want to draw your attention to an art installation called “Of all the people in all the world the rice show“. In this work they use grains of rice to represent people in different categories: a pile that shows the number of children who died from not being vaccinated last year, or a massive pile of all the current refuges next to a tiny pile representing the worlds billionaires. Being able to touch statistics can make them more engaging and bring instant understanding.
So how did I use R in this project? First, I used the iGraph package to make a network from a edge list, which is simply a two column dataframe that represent the folks retweeting (list 1) and those they retweeted (list 2).
edge.list.df <- data.frame(from=retweeters, to=retweeted) g <- graph.data.frame(edge.list.df, directed=TRUE)
Now that I have the network, I can use the features of the igraph package to set the size and colors of the nodes and edges (code not shown, but you can see an example here). Next, I need to make the 3D model. Fortunately, iGraph will do that for me as well, provided I use the rglplot.igraph function. This is iGraph’s version of rglplot from the RGL package. The iGraph version first creates a network layout with x, y, and z coordinates for each node, and then calls RGL functions to create each node as a sphere and all the edges as shade3d objects. Thus, by just calling the rglplot.igraph function, iGraph builds the model for you and holds it in memory. The model can be queried, modified and exported.
rgl.open() rgl.bg(color="black", alpha=c(.3), back="fill", sphere = FALSE, fogtype = "none", line_antialias = TRUE) rgl.viewpoint(0, 0, fov=100, zoom=.5) rglplot.igraph(g, edge.arrow.size=0, edge.arrow.width=0)
The plot above shows the full network rendered in the RGL viewport. In this viewport I can examine the model by zooming in and spinning the model around. I can even capture a png of the model (shown) using the rgl.snapshot function.
The network shown above is a bit too complex for today’s 3D printers; the gossamer thin links won’t hold up the nodes. Also we are often interested in, for example, power structures at the core of the network. So for this first 3D printing experiment I removed smaller nodes by deleting them from the network using the iGraph function, coreness. Coreness basically gives each node an integer score of how ‘core’ they are to the network, where lower numbers mean the nodes are further out in the periphery and higher numbers mean they are better connected to other well connected nodes at the center of the network.
small.frys <- which(V(g)$coreness.all < 4) g <- delete.vertices(g, small.frys)
Now I replot the 3d network and make any additional adjustments. Once I am ready, I keep the 3D view port open and call one of RGLs export functions. In this case I export to a stereolithography file, which is a typical format for 3D printers:
writeSTL("~myNetworkPrintFile.stl")
Note that you can also export the network as an object file and import it into other 3D molding programs, like Blender.
writeNetworkOBJ("~myNetworkObject.obj", withNormals=T, separateObjects=T)
Note that for both of these calls I do not pass the network in. As long as the RGL viewport is still open I can export because the model is still in memory (as an aside, you can actually save the scene, including the model, as well). In any case, bringing the model into something like Blender allows finer control over the model, 3D visualization and also allows you to export your final result to an .stl file. In this case, I used Blender to scale the model. In the image below, the blender version of the model is on the left, and the final 3D printed version is on the right.
For the final step I created an account at Shapeways, uploaded my file for their automated model checker, and waited for my network to show up in the mail. The site allows you to choose from different kinds of materials, each with its own costs, pros and cons. I chose the material that was most likely to work for a model with a lot of overhangs (which also turned out to be cheapest as well). The result cost me about $20.00.
Networks aren’t the only kinds of 3D objects you can make with R. For example, the Revolutions blog has posts here and here that go through the process as well. Also, a new package called r2stl is out, though I haven’t worked with it yet. The r2stl package requires you to create your own meshes for you objects, so for networks, iGraph and RGL are the way to go.
That’s all for now. You can contact me on Twitter @JeffHemsley. Happy to answer any questions.
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.