Convierte tu GGplot en una animación 3D con R y Rayshader

¿Pensando en usar 3D en R? En este post te enseñamos a convertir tus gráficos R ggplot en gráficos 3D. ¡Lleva tus gráficos en R a otra dimensión! ;)


En 7 minutos, seremos capaces de convertir nuestras gráficas generadas con ggplot en espectaculares plots en 3D, ¡y ademas interactivos! Podrás embebernos en HTML/Rmarkdown, o incluso mejor, podras exportarlo como mp4 en una animacion rotatoria para sacarle todo el jugo a tus datos!

Como caso de uso, vamos a visualizar la edad media de los municipios españoles cruzando datos del padrón con los datos GIS, para posteriormente visualizarlos en 3 dimensiones.



1. Introducción


En las últimas semanas, un ‘nuevo’ paquete de R ha centrado el interés de cierta parte de la comunidad. Decimos ‘nuevo’ porque se ha incorporado recientemente al CRAN, aunque realmente el primer commit realizado por su autor su repo de Github data de hace más de un año. Su nombre es rayshader y en palabras de su propio creador:


“rayshader uses elevation data in a base R matrix and a combination of raytracing, spherical texture mapping, overlays, and ambient occlusion to generate beautiful topographic 2D and 3D maps”


Bajo mi punto de vista, Tyler Morgan-Wall (el autor del paquete) dio con la tecla cuando incorporó al paquete dos nuevas funciones, plot_gg() y render_movie(). La primera de ellas nos permite convertir con 2 líneas de código nuestra visualización en ggplot a una figura 3D de una manera realmente facil y eficiente. La segunda de ellas renderiza esta figura y la anima, poniendo al alcance del usuario diversos parámetros para controlar el zoom, los fps, ángulo, inclinación…



Las nuevas funcionalidades y planteamiento del experimento

La única condicion que debe cunplir tu gg-visualización es tener como aesthetic color o fill, y en algunos casos también puedes jugar con el size

En demasiadas ocasiones, la visualización de datos en 3D no es la mejor opción a elegir, tal y como hablaremos un un futuro post. Por este motivo, he intentado traer un ejemplo donde el uso de la tercera dimensión aporte valor al análisis.

Este ejemplo práctico consistirá, como ya hemos avanzado, en la visualización en el mapa de España la edad media en cada municipio. ¿Chulo? Para ello necesitaremos:

  • Los datos del censo sobre las estadísticas de la población (en este caso la edad media) por cada municipio. Estos datos los obtenemos de la web del INE.

  • Los datos GIS con las coordenadas de cada uno de los municipios que componen España.

Una vez que tengamos estas dos fuentes de datos combinados, los visualizaremos y posteriormente exploraremos su renderización en un clip 3D con la figura rotando tal y como se ve en la imagen que encabeza este post.

¡Vayamos paso por paso!


2. CdU: Visualizando la edad media de cada municipio en España

Una vez hemos establecido el objetivo principal y las diferentes fuentes de los datos, podemos proceder a la descarga y tratamiento de los mismos.


2.1- Descargando los datos del censo

Como digimos, para llevar a cabo nuestro propósito, necesitamos acceder a dos fuentes diferentes de datos. Usaremos el portal de datos abiertos del INE para descargar la edad media en cada municipio español. Después de una búsqueda bastante ardua por su web, encontramos la información que buscábamos. Os dejo este link donde teneis acceso a lo que ellos llaman como estadísticas contínuas

link.

Con el objetivo de no irnos por las ramas, descargaremos directamente el fichero del 2018. Sin embargo, sí que es interesante citar la iniciativa INEbase de facilitar el acceso y la navegación en esta fuente de datos de INE.

Comenzamos cargando (o descargando) los paquetes necesarios para nuestro análisis. En un futuro post o tip compartiremos una función nuestra para la carga (o descarga en caso necesario) múltiple de paquetes en una sola linea.


Descargando el fichero del INE 2018:


Parseamos los datos con el objetivo de conseguir un dataframe que consista en name, postal_code, average_age


2.2- Descargando datos GIS

La segunda fuente de datos que vamos a utilizar son los datos geográficos de los municipios españoles, los cuales cruzaremos con los censales anteriormente descargados para pintar la edad media en sus respectivas coordenadas.

Descargando los daots GIS:

Tratamos estos datos para convertirlos de formato espacial a datos tabulares. Para este caso concreto de 3D, las Islas Canarias podrían deformarnos el gráfico, por lo que decidimos permanecer concentrados en nuestro objetivo didáctico y filtramos estas coordenadas. Por supuesto es posible mantenerlas sin perjudicar el gráfico, alterando sus coordenadas y acercándolas a la península. ¡Esto te queda como tarea para ti!

Para llevar a cabo este procesado de los datos, usamos la función fortify para no depender de más paquetes. No obstante esta funcion nos lanza un warning sugiriendonos el uso de la función tidy() del paquete broom.

Para terminar, joineamos los dos datasets creados para conformar el tablón final, el cual vamos a usar como base para crear las gráficas. Apuntar que usamos left join como forma de mantener los datos geos y no perder coordenadas en el plot.

Como buena práctica, comprobamos el número de NAs generados a partir de este left join. Estos NAs serán municipios de los que tenemos coordenadas pero no contamos con información sobre la edad media.

Vemos que los valores perdidos representan únicamente el 1% del total de filas, por lo que vamos a imputarlos con el dato del código postal previo. Es cierto que podemos mejorar esta imputación, pero para nuestro propósito será suficiente debido al pequeño porcetaje del total que representan. ¡Vuelve a quedar de tu mano mejorarlo y comentárnoslo!


2.3- Visualización con Ggplot

Inspirado en gran medida en http://blog.manugarri.com/making-a-beautiful-map-of-spain-in-ggplot2/

Con este dataset final, plotearemos las variables que representan las coordenadas en el eje X e Y y en primer lugar representaremos la edad media mediante la paleta de color. Las tonalidades rojas son asignadas a edades superiores y las azules a las edades medias más jóvenes. Conseguimos esto mediante el aesthetic fill de Ggplot.


2.4- Visualización en 3D con Rayshader!

El anterior gráfico estaba bastante bien. En el podemos facilmente distinguir los municipios con la edad media más alta y los municipios más jóvenes. Sin embargo, los ojos humanos no son capaces de distinguir fácilmente entre colores próximos ni distinguir la magnitud de las diferencias en esta escala. Por lo tanto, ¿qué tal complementarlo con un nuevo eje?

Veamos como hacerlo y que tal queda


Hmm dijiste algo sobre render_movie()… Qué tal si lo animamos?


2.5- Animación 3D con Rayshader

En el gráfico anterior, la variable edad media queda bastante más entendible por el ojo humano en la dimensión añadida. Aquí la elección del ángulo e inclinación correctos es un punto esencial. Pero, ¿y mejoramos la interpretabilidad rotando el gráfico?

Esto es de lo que se encarga la siguiente función:

Carlos Vecina
Carlos Vecina
Senior Data Scientist at Jobandtalent

Senior Data Scientist at Jobandtalent | AI & Data Science para aportar valor en la empresa