Resources

image: thumbnail.jpg

Transcript#

This transcript was generated automatically and may contain errors.

Hi everybody. Thank you. My name is Tyler Morgan-Wall and today I'm going to be talking to you about 3D mapping, plotting, and printing with rayshader.

So a little about myself. I have a PhD in physics from Johns Hopkins University and I work at the Institute for Defense Analyses in Alexandria, Virginia. I'm the developer of four packages, rayshader, skipper, rayfocus, and adjusted cranlogs, but this slide mostly exists in case you don't recognize me from my very outdated Twitter profile picture because we all look a little different on the internet. I'm going to answer a few questions in this talk. First and foremost, what is rayshader, why did I develop it, and how can you use it to make beautiful maps and visualizations? Second, I'm going to spend a few minutes trying to convince you that 3D plots aren't as bad as some people make them out to be and can be an effective tool in your visualization arsenal. And finally, I'm going to talk a bit about some of the non-coding activities that you can do to develop your projects and how you can take advantage of the great R community.

What is rayshader?

Rayshader is a package designed to create maps in R. And by create maps, I mean generating maps directly from elevation data. This is in contrast to building maps off of preexisting tiles. There's nothing wrong with using tiles to build your map, but it does limit your aesthetic options to whatever the creator of those tiles decided on. By generating our maps directly from the source elevation data, we can have full control over their appearance.

So this is what happens when you plot elevation data with base R using the image function. The code is on the left and the output is on the right. This is Hobart, Tasmania, but looks more like two amoebas dueling it out in pond scum, or as base R calls it, terrain colors. Here, the Hobart object is nothing more than a base R matrix. Here is the rayshader version of that plot using spherical shading. It's a much more naturalistic view of the data. While you lose the direct mapping of color to elevation, you gain a much more human understanding of the landscape's contours. Note how details appeared that weren't apparent in the base R plot, namely the fact that there is a river between these two mountains.

Rayshader is built around elevation data, and building a plot works similarly to how you build a plot in ggplot with layers. Here, I've added a water layer simply by calling the detect water and add water functions in rayshader with the elevation matrix. This overlays a water layer on top of the sphere shade layer. Now, rayshader's name comes from the fact that it uses ray tracing to shade topographic maps, so much like we added our water layer here. We can add a shadow layer simply by calling the add shadow function with the rayshade function. This traces rays from each point on the elevation matrix, determines if that point is in shadow or light, and shades it appropriately. The add shadow function layers it onto the existing plot, passed in using the pipe operator. We can continue stacking different types of shadows with additional calls to add shadow. Here, we add an ambient occlusion layer, which models atmospheric scattering and makes valleys darker than ridges.

We now have, in my opinion, a beautiful 2D topographic map, but if you think about it, our data is already inherently 3D, X, Y, and Z elevation. So, in rayshader, transitioning from 2D to 3D is as simple as swapping out the plot map function with the plot 3D function. Note how the only data used to generate all of this is the base R matrix, no special data structures. Once you're able to get your data into that form, you can focus solely on perfecting the aesthetics of your map. Speaking of aesthetics, changing them in rayshader is incredibly simple.

There are seven built-in palettes, and you can create your own using the create texture function. The last one is the unicorn palette. However, one thing that bothered me when I first made that plot was, although it is very cool, as a 3D surface, it was representing solid earth, but the plot itself looked flimsy and infinitesimally thin, like you could just blow it away if you breathed too hard. So, I made it so you could set solid equals true in the plot 3D function, and rayshader would automatically render a solid 3D object. This changes the aesthetic from pseudo-3D surface to actual 3D model, something you could imagine holding in your hand, putting at your desk, and fidgeting around with. You don't have to imagine, though, because I built into rayshader the ability to export your maps to a 3D printable format with no external software required.

So, this is Hobart, Tasmania, the same place. Note that the top figure is rendered in rayshader, and the bottom figure is rendered in real life. Note how closely the two matches as it rotates, and compare the similarity to the shadows on the surface of the 3D model. I have the model right here with me if you want to see me afterwards and check it out.

Most importantly, adding this feature led me to the moment I knew I had made it as an R programmer. Because my cat finally showed an interest in what I was doing.

Most importantly, adding this feature led me to the moment I knew I had made it as an R programmer. Because my cat finally showed an interest in what I was doing.

So, none of the built-in datasets in R really showcased all these features, so I included a new dataset with rayshader of Monterey Canyon in Monterey Bay, California. Here, you can see where rayshader really starts to shine. Combined representations of 3D representations of topographic and bathymetric data.

So, our planet is going through an immense period of change, and much of that change is focused around our coasts. One of the main goals I had with rayshader was to make it dead simple to make beautiful, engaging visualizations combining land and water. Here, all the user has to do to model a changing coastline is to set the depth of the water in either plot 3D or the render water function. Rayshader handles all of the rendering and slicing.

A good visualization needs context, and the render label function allows you to drop labels seamlessly into your maps, just with the row and column index in your matrix. The render label you can easily customize with your line shape, font width, height, color, anything. You can do an RGL. So, annotating your maps is a very serious use of rayshader. This is not. But, in addition to adding shadow and water layers, you can also overlay arbitrary images and data on your maps. Normally, you could imagine this being used for something serious like, you know, public health data or pollution statistics, but so far I've mostly used it to throw animated GIFs on my maps. Your visualization is your choice.

One issue, though, I had with the raw 3D visualizations is how CG they looked. I wanted rayshader's output to look like a real model. So, one way to do that was to make it look like it was being imaged by a real camera. So, this is the render depth function, where I built a virtual camera into rayshader that simulates a depth of field effect. The interface to do this is dead simple. You just pass in a focal point and focal lens or f-stop, and you just call the render depth function, and then rayshader renders this beautiful post-processing bokeh effect. Finally, you're not limited to square maps with rayshader anymore. Simply by setting the points you want to remove to NA, R's missing value, you can shape your map into anything you want. Rayshader intelligently slices and renders the resulting map, and you can 3D print it. So, it's an easy gift for all of your geographically inclined friends.

Coming soon to rayshader

So, all of that covers the current state of rayshader, but there's a lot of cool features coming soon, several of which I'm excited to announce for the first time here at RStudio conference. So, soon you're going to be able to explore your rayshader visualizations in virtual reality, augmented reality, as compact HTML-embeddable 3D assets, and in external 3D software such as Blender. And this is possible because I added to rayshader the ability to export to GLTF 2.0, which is the next-gen 3D asset file transmission format. So, this means your data visualizations are no longer stuck in R. You can include them in your, you can make them, put them in the web and include them in standard 3D graphics workflows.

So, that sums up the current and future state of rayshader, but I think I know what many people came here to see. 3D GG plots, which are coming next. That will be in the next release of rayshader. But before I release this to the public, I do need to address the small contingency of people who would say that I shouldn't even release this feature because 3D plots only exist to impede interpretation and are an affront to good visualization practices.

Are 3D plots always bad?

So, are 3D plots always bad? No. The idea of 3D plots being bad stems from the fact that 3D has often been used gratuitously, where the data itself is inherently 2D or 1D and 3D is just added for visual fluff. When a data has legitimate 3D mapping, creating a 3D plot is perfectly fine. There's also the idea that since the display medium is 2D, 3D plots are not appropriate. So, here's two examples from the source of all things cartographic in the USGS. The Atlas of Oblique Maps, published in 1988, contains beautiful 3D representations of topographic and bathymetric data. Unlike a 2D contour or color map, you don't need to have a degree in cartography or to read a color bar to know what's going on. The 3D structure of the landscape is immediately apparent. Some might say, well, that's just illustration. That's not data viz. But that's not the case. The cartographers of the USGS actually created these maps by using what's called an isometrograph, which maps contours to their 3D projection. These maps were based off of actual data visualized in 3D. And even in 1988, cartographers understood something very important about these types of visualizations. They are incredibly engaging and easy to understand. And this type of engaging tool is important when trying to communicate complex ideas and analyses about our changing planet.

Each visualization is part of a story, and sometimes the idea that the visualization needs to be so precisely constructed that the reader could take a ruler to the plot and reconstruct the data set manually needs to take a backseat to the story you're trying to tell. This visualization was not made with rayshader, but I thought it was a great example of a 3D map that tells a story on its own. The change in groundwater in Southern California over time shows how the water table is breathing. Would this visualization be as effective or engaging without the 3D? I don't think so. The 3D brings the data to life in a way a color map or a use of small multiples wouldn't. This animation is likely what caused this article to go viral and be exposed to thousands of people. And science that is communicated to the general public and stokes their interest is infinitely more valuable than science that just stokes the interest of those in academia. And 3D visualizations are a great way to do just that.

science that is communicated to the general public and stokes their interest is infinitely more valuable than science that just stokes the interest of those in academia.

Non-coding activities that propel your projects

So finally, I'm going to talk a bit about how non-coding activities can propel your projects forward. As I found out with rayshader and also act as a nice respite for when you've crashed R 20 times in a row using C++. So writing about your projects is more than just marketing. It's also a great tool to get yourself brainstorming. When describing the original 3D modeling blog post I wrote about this, I wrote, I didn't want the map to look like a carefully crinkled sheet of paper. I wanted a 3D representation that looked like a paperweight, which immediately got me thinking, why not try 3D printing it? What would it take for me to implement that? What do I need to learn to do this? In this case, writing led to an idea, which led to, I think, a really cool feature.

Creating animations that show off on Twitter is fun, but they also serve as double duty, as tests of rayshader. I found so many bugs by producing these animations. Here you can see one where the text label, when it's underneath a transparent surface, only disappears at certain angles. This is still a bug, but anyway. But I found lots of floating point issues and all these things that only happen out of two out of 360 frames in my animations. So it's a really great way to kind of test your software if you make something, you know, visual based.

And finally, I found when I've been making rayshader, I've gotten three important types of feedback. The RStats community is a great resource you should definitely take advantage of. Interacting with the greater community, again, is not just marketing. The feedback you get can dramatically improve your code. When you post your project online, you get these three different important types of feedback. Inspiration, of course. Seeing people do unexpected and just plain cool things with your project. When you have hundreds of creative, capable, and analytical minds working with your software, they can do things that you're not even going to think of. This is just a small selection of some of the cool projects over the last eight months rayshader has existed. And some very cool stories. I think Hadley said that it was the quickest. I think a package has gone from a lease to in a major newspaper with this Wall Street Journal story. But yeah, the stuff I've seen has been incredible.

Then there's shame. So if you ask the Internet how to do something, in my case, develop a ray tracer to shade topographic maps, you'll likely get a kind of passive-aggressive link to the Wikipedia page for ray tracing with maybe a link to a Stack Overflow post. But if you make an attempt and tell the Internet that you've created a ray tracer to shade topographic maps, you'll get a bunch of beautifully pedantic people coming out of the woodwork to do an in-depth code review to tell you exactly what you did wrong. Which, if you can stomach it, is a great way to help figure out where you want to bring your project. So you're never too good to find all of your bugs, so you need the community to find your bugs for you. And sometimes it can be good to get shamed into programming things that aren't exactly fun to program, like making your programs more efficient or use less memory. I had to do this after this great blog post that came out about entirely how slow rayshader was.

So finally, motivation. This is just a montage of tweets over the last few months of people expressing how excited they are in following what's going on in rayshader. Seeing people's excitement and interest in your project, as Marie Kondo puts it, sparks The R community in particular is one of the nicest and most supportive programming communities out on the Internet. So if you have a project you are working on that you are proud of, it's likely that there will be a bunch of people online that will love it too.

So, in summary, make maps with rayshader, use 3D, write about your projects, and tweet your heart out. Thank you.

Q&A

Oh, and if you ask a question, I have a little 3D printed volcano data set that I'll give it to you. You're speaking in front of hundreds of people too.

Hey, I'm curious if there's a way to adjust the light source that's used for the shadow that you can add. Yeah, no, that's one of the arguments in rayshade. You can adjust the width to make it a finite size source, but yeah. Super cool. Thanks. And you get a volcano.

Can you kind of explain a little bit why I would want to see my maps in augmented reality? Well, why wouldn't you? It's super cool. It's cool, but what's the practicality? You know, it's just, I don't really know why. I mean, it's just one of those cool things that you can do and it's like, why not? I think it's like, I actually have, if you want to meet me afterwards, I have a little marker. I can show you how it works and it operates on your phone and you can actually hold the marker and hold the 3D object in your hand. I think it's more of a science communication thing to show your data in real life and it's just like, normally people might look at it and be like, oh, data, whatever. But if you can actually give them and let them then hold it, I mean, even if it's really boring data, they could be like, wow, this is so cool. Groundwater.

I was wondering if it was possible to see the different types of biological environments, so different types of forests that you could put on your 3D map. So you can use anything, actually, for the actual image file. So rayshade, those functions just create an image file which maps onto there. So if you actually imported your images or created a different texture to represent those regions, you could put that on your 3D map.

So one more. If you were to overlay a street map onto... Yes. So is that, you just need the... Yeah, you just need an image file with the same extent, the same range, and then you could use the overlay image function. You can specify transparency, or it can have transparency so you can lay it on top. Awesome, thanks.

All right, we have one last question here and then you can ask Tyler after. Related to the first question, can you set the time of day of the sun? Yeah, actually, that's been a longstanding issue. That was one of the original features I wanted to add, was just give a date, time, and lat, long to specify the place of the sun. There's some code out there that does that. It's pretty simple to do. But yeah, you can do that manually for now. But I've kept that issue open for six months because I've been meaning to do something for that.