💡 Datos para la actividad:

Datos.

Scripts.

INTRODUCCIÓN

La mayoría de los mapas temáticos que se producen son de tipo cuantitativo. Su objetivo es informar de cuánto varía una variable(atributo) sobre en territorio siguiendo criterios de cantidad. Dependiendo del tipo de fenómenos geográfico a representar, el propósito, su escala etc… existe una tipología diversa.

Los tipos fundamentales de mapas cuantitativos son los siguientes:

Para desarrollar la práctica son necesarios los siguientes paquetes:

Los paquetes necesarios para la realización de la actividad son los siguientes_

library(sf)                              # Para el manejo de ficheros vectoriales.
library(terra)                           # Para el manejo de fichero raster.
library(tmap)                            # Para la representación cartográfica.
library(tmaptools)                       # Paquete de ayuda para tmap.

Los datos necesarios para la realización de esta actividad se encuentran en:

MAPAS DE DENSIDAD DE PUNTOS

Es el método básico para mostrar la distribución de un fenómeno geográfico (por ejemplo, la población, las cabezas de ganado, etc) sobre el territorio. Como su nombre indica, la información cuantitativa se representa mediante puntos. El punto es la forma más simple de representación cartográfica, y no muestra variación ni de forma ni de tamaño; cada uno de ellos tiene un valor preestablecido por el investigador.

Aunque es posible la representación de variables contínuas, se recomienda su uso con datos de naturaleza discreta y expresados en forma absoluta, pues la densidad de puntos hace referencia a la magnitud del fenómeno.

Entre sus ventajas es de destacar la fácil comprensión de la distribución del fenómeno sobre el territorio, pero se recomienda un análisis previo de los factores que controlan la distribución de la variable en el mapa.

Para la realización de esta práctica disponemos de los datos del objeto mtq. Este objeto tiene la siguiente estructura:

str(mtq)

Este objeto cuenta con los siguientes atributos:

Tmap no dispone de ningún tipo de función para representar este tipo de mapa cuantitativo. Por ello, hay que realizar previamente una serie de procedimientos para crear el mapa en formato shp con el paquete terra. Es mapa será utilizado posteriormente para crear el mapa definitivo en tmap

Esta primera fase comienza creando un objeto SpatVector (formato propio de terra) a partir del formato vectorial original. Este nuevo objeto se denominará mapa_provisional. Para verificar que este procedimiento es correcto, se cartografía. La función dots() del paquete terra crea un objeto gráfico con la ubicación de los puntos distribuidos sobre el territorio. A continuación se convierte en un objeto vectorial de puntos.

mapa_provisional <- vect(mtq)

plot(mapa_provisional, 
     lwd=3, 
     col="light gray", 
     border="white")

mapa_puntos <- dots(mapa_provisional,            # Objeto vectorial que contiene la variable a representar.
                    "pob",                       # Variable del dataframe a representar
                    1000,                        # Divisor, o número indicando cuántos casos representa cada puntos en el mapa.
                    col="black",                 # Color de los puntos.
                    cex=.75)                     # Tamaño de los puntos.

lines(mapa_provisional)                          # Se dibujan encima las líneas correspondientes a las fronteras entre ayuntamientos.

Para poder utilizar ese objeto en tmap hay que volver a pasarlo a formato sf mediante la siguiente expresión:

mapa_densidad_puntos <- sf::st_as_sf(mapa_puntos)

Finalmente, se puede dibujar el mapa de densidadde puntos:

tm_shape(mtq) +                                                                 # Mapa base
  tm_graticules() +
  tm_polygons() +                                                               # Representa el fichero vectorial.

tm_shape(mapa_densidad_puntos) + 
 tm_dots(size= 0.25,                                                            # Tamaño del símbolo.
         shape = 21,                                                            # Tipo de símbolo.
         col="black") +                                                         # color del símbolo.
 
tm_layout(main.title = "Población de La Martinica",
          main.title.fontface = "bold", 
          legend.title.fontfamily = "monospace") 

Una alternativa es el uso del paquete dots cuyos gráficos son producidos bajo el paquete **ggplot2”, que no se utiliza en la asignatura. No obstante, se mostrar una sintaxis sencilla acerca de cómo producir mapas de densidad de puntos con ambas herramientas. En primer lugar, se cargan los paquetes necesarios:

library(dots)
library(ggplot2)

A continuación se crea el mapa de densidad de puntos

dots::dots(shp = mtq,                         # El objeto en formato vectorial
           cols = pob,                        # La variable a representar.
           divisor = 500) +                   # El divisor, o número indicando cuántos casos representa cada puntos en el mapa. 
  labs(title = 'Mapa de puntos de la población de La Martinica') + 
  theme_void()

📝 ACTIVIDAD DE EVALUACIÓN CONTINUA MAPA DENSIDAD DE PUNTOS

  1. Crea un mapa de densidad de puntos con tmap siguiendo el procedimiento señalado en la explicación. con las siguientes especificaciones:
  • Utiliza la variable “activos”.

  • Cambia el color del símbolo por “rojo” (“red”).

  • Cambia el tipo de punto mediante el argumento shape

  • Incluye un título apropiada para la variable en cuestión

MAPA DE SÍMBOLOS PROPORCIONALES

Este tipo de mapas utilizan diferentes símbolos (lineales, superficiales, volumétricos) escalados (es decir, varía su tamaño dentro del mapa), en proporción a las cantidades a representar. El símbolo más utilizado es el círculo, aunque también son frecuentes mapas con cuadrados o triángulos. El símbolo proporcional informa de la localización de un fenómeno y, simultáneamente, del valor de ese fenómeno. Normalmente, estos mapas representan cantidades totales (por ejemplo la población).

A la hora de establecer cómo varía proporcionalmente el tamaño de los símbolos en función del valor de la variable representadas (escalado matemático), el uso de círculos causa una cierta subestimación del tamaño; en el caso de esferas es difícil la percepción de los datos, e incluso la percepción de las diferencias entre datos. La utilización de puntos y círculos conjuntamente, puede resultar muy efectiva para superar alguna dificultad en el diseño del mapa

Por último, es necesario que el mapa incluya una leyenda en la que se informe de la relación entre el tamaño del símbolo y la cantidad representada en el mapa.

En función del tipo de datos con se trabajará existen dos tipos de mapas de símbolos proporcionales:

Mapa de símbolos proporcionales con puntos

Como se ha señalado en páginas anteriores, en este caso se trabaja simultáneamente con dos objetos espaciales:

  • El objeto población, cuya geometría servirá de mapa base.

  • El objeto casas, sobre cuya geometría se dibujarán los símbolos proporcionales.

El objeto poblacion tiene la siguiente estructura:

str(poblacion)

Sus atributos son los siguientes:

  • id: el indicador de una sección censal.

  • pob_nacional: el porcentaje de población nacional dentro de esa sección censal.

  • desempleados: el porcentaje de desempleados dentro de esa sección censal.

  • calificacion_escolar: el porcentaje de población con estudios de bachillerato dentro de esa sección censal.

Por su parte, el objeto casas cuenta con la siguiente estructura:

str(casas)

Los atributos son dos:

  • UID: un indicador.

  • precio: el precio de la vivienda.

El objetivo de esta práctica es la creación de un mapa de símbolos proporcionales que representa el valor de cada una de las casas. Se comenzará trazando un mapa base en blanco con la transparencia de los bordes de cada unidad censal en 0.4.

tm_shape(poblacion) + 
  tm_borders(alpha=.4)

A partir de ese mapa base se añade la ubicación de las viviendas, que serán representadas como puntos rojos (función tm_dots) sobre el mapa base. En este caso, la información visual sobre el valor de la vivienda se conseguirá mediante diferentes gamas del color rojo. Además, se añadirá un título a la leyenda,

tm_shape(poblacion) + 
     tm_borders(alpha=.4) +                                                     # Nivel de transparencia de los bordes del shapefile
tm_shape(casas) + 
     tm_dots(col = "precio",                                                    # Variable representada en forma de puntos.
             size = 0.15,                                                       # Tamaño del punto.
             palette = "Reds",                                                  # Color de los puntos.
             style = "quantile",                                                # Método de extracción de las categorías.
             title = "Precio pagado (€)") +                                     # Título de la leyenda
tm_compass() +                                                                  # Símbolo del norte
tm_layout(legend.text.size = 0.6,                                               # Tamaño del texto de la leyenda.
          legend.title.size = 1.3,                                              # Tamaño del título de la leyenda.
          frame = FALSE,                                                        # Se elimina el marco alrededor del mapa
          main.title = "Precio de la vivienda en San Julián",                   # Título del mapa
          main.title.fontface = "bold") 

También se puede crear un mapa de símbolos proporcionales sustituyendo la función tm_dots() por la función tm_bubbles(), que tiene argumentos similares. En este caso, se jugará no sólo con el color sino también con el tamaño del símbolo a partir del atributo “precio”. Las diferencias de tamaño entre objetos son relativamente fáciles de reconocer en los mapas, siendo por tanto adecuadas para representar variables cuantitativas (numéricas), donde los valores pequeños se relacionan con objetos pequeños y los valores grandes los presentan objetos grandes. Los tamaños grandes también pueden utilizarse para atraer la atención del espectador.

tm_shape(poblacion) + 
  tm_borders(alpha=.4) + 
tm_shape(casas) + 
  tm_bubbles(size = "precio", 
             col = "precio", 
             palette = "Blues",
             style = "quantile", 
             legend.size.show = FALSE, 
             title.col = "Precio de la vivienda") +
tm_layout(legend.text.size = 0.6,                                               # Tamaño del texto de la leyenda.
          legend.title.size = 1.3,                                              # Tamaño del título de la leyenda.
          frame = FALSE,                                                        # Se elimina el marco alrededor del mapa
          main.title = "Precio de la vivienda en San Julián",                   # Título del mapa
          main.title.fontface = "italic")

📝 ACTIVIDAD DE EVALUACIÓN CONTINUA MAPA CON SÍMBOLOS PROPORCIONALES (I)

Crea un mapa en el que se combine una capa con los perfiles de los continentes (objeto metro del paquete tmap) y un mapa con símbolos proporcionales a la población de las ciudades del mundo en el año 2030 tamaño de las ciudades (objeto metro).

Mapa de símbolos proporcionales sobre polígonos

Podemos cambiar los tamaños de todos los objetos utilizando el argumento size (Figura 6.11:A).

tm_shape(poblacion) +
  tm_borders() +
tm_shape(poblacion) +
 tm_symbols(size = 0.3) 

On the other hand, if we provide the name of the numerical variable in the size argument (e.g., “elevation”), then symbol sizes are scaled proportionally to the provided values. Objects with small values will be represented by smaller circles, while larger values will be represented by larger circles (Figure 6.11:B).

tm_shape(poblacion) +
 tm_symbols(size = "calificacion_escolar") 

We can adjust size legend breaks with sizes.legend and the corresponding labels with sizes.legend.labels (Figure 6.11:C). However, this only modifies the legend, not the related objects.

tm_shape(poblacion) +
 tm_symbols(size = "calificacion_escolar",
            title.size = "calificacion_escolar",
            sizes.legend = c(10, 100),
            sizes.legend.labels = c("low", "high")) 

En este caso, sólo se trabaja sobre un único objeto vectorial, el objeto mtq, cuya geometría sirve de mapa base y cuyo atributo pob es representado gráficamente mediante círculos proporcionales.

tm_shape(mtq) +
  tm_polygons() +            # Fondo gris
tm_shape(mtq) +                                     # por defecto bubbles en el centroide del polígono
    tm_bubbles(size = "pob",
               col = "orange",
               alpha = 1,
               title.size = "Población total") + 
tm_compass(position = c("left", "top"), 
             size = 1.5, 
             show.labels = TRUE,
             color.light = "black") +
tm_scale_bar(position = c("left", "bottom"), 
               breaks = c(0,5, 10)) + 
tm_credits("Fuente: Censo 2018",                                                # Fuente
             position=c("right", "bottom"), 
             size = 0.4) +
tm_layout(main.title = "Población de La Martinica",
          bg.color = "lightcyan",                                               # Color del fondo.
          frame = TRUE,                                                         # Marco del mapa.
          inner.margins = c(0.10, 0.10, 0.10, 0.10)) +                          #Tamaño del territorio dentro del espacio gráfico.
tm_xlab("Longitud") +
tm_ylab("Latitud")

📝 ACTIVIDAD DE EVALUACIÓN CONTINUA MAPA DE SÍMBOLOS PROPORCIONALES SOBRE POLÍGONOS

MAPAS DE ISOLÍNEAS

Un mapa de isolíneas es la representación en dos dimensiones de una superficie estadística suavizada, a través de elementos lineales, denominados isolíneas. Las isolíneas, como son las curvas de nivel o las isobaras, etc…), son líneas que unen puntos en donde una variable toma un mismo valor. Al mostrar la variación espacial de un fenómeno, podemos interpolar los valores entre dos isolíneas y conocer el valor teórico en cualquier lugar del espacio.

Es el método más utilizado para la representación de variables contínuas, haciendo uso tanto de de valores absolutos (altitud, temperatura etc.) como de valores derivados (promedios, proporciones, etc.). La visualización de datos en formato ráster depende del tipo de variable (contínua o categórica), su resolución y el número de capas.

La función de tmap adecuada para este tipo de mapas es tm_raster().

Mapa de relieve

Para representar el relive se debe trabajar con con Modelo Digital del Terreno, que es un ráster continuo. Para realizar esta tarea debe importarse un fichero en formato ráster.

mdt <- rast("D:/G2040/raster/zion/srtm.tif")

Un mapa topográfico requiere un fichero original en formato raster que incluye una variable continua (en este caso, la altitud); tm_raster(). El argumento style = cont es más adecuado para representar fenómenos que varían de manera progresiva sobre el territorio.

tm_shape(mdt) +
   tm_raster(title = "Altitud (mnm):", 
             style = "cont", 
             palette = "-Spectral") +
   tm_layout(legend.outside = TRUE)

Al igual que en la mayoría de los paquetes de software SIG, los valores de altitud se pueden agrupar en rangos o categorías con colores diferentes. El argumento style = pretty redondea cada categoría o intervalo a números enteros.

tm_shape(mdt) +
  tm_raster(title = "Altitud (mnm)", 
            style = "pretty",
            palette = "-Spectral") +
tm_layout(legend.outside = TRUE)

El argumento style = equal divide la variable continua en intervalos de igual longitud (sólo es apropiada cuando la variables representada muestra una distribución uniforme).

tm_shape(mdt)+
  tm_raster(title = "Altitud (mnm)", 
            style= "equal",
            palette = "-Spectral") +
  tm_layout(legend.outside = TRUE)

El argumento style = quantile divide la variable en cuantiles (ver tema 5), por lo que cada intervalo incluye el mismo número de observaciones.

tm_shape(mdt) +
   tm_raster(title = "Altitud (mnm)", 
             style= "quantile", 
             palette = "-Spectral") +
tm_layout(legend.outside = TRUE)

Finalmente, con style = jenks un algoritmo identifica “puntos de ruptura” dentro de los datos creando los intervalos de manera que cada categoría sea lo más homogénea posible, al tiempo que maximiza la diferencia entre ellos.

En el siguiente conjunto de ejemplos se muestra la aplicación de las paletas de colores ColorBrewer2; estas paletas se pueden aplicar cuando se utilizan métodos clasificados o continuos. El argumento n = 7 representa el número de categorías o intervalos que desamos que el programa represente.

tm_shape(mdt) +
   tm_raster(style= "quantile", 
             n = 7, 
             palette=get_brewer_pal("Greys", plot=FALSE)) +
tm_layout(legend.outside = TRUE)

La paleta de colores puede adquirir otras modalidades, por ejemplo inviertiendo los colores palette=get_brewer_pal("-Greys", n = 7, plot=FALSE).

Finalmente, es posible incorporar al mapa topográfico información geográfica adicional superponiendo capas: límites administrativos, montañas más elevadas etc.

tm_shape(mdt) +
  tm_raster(title = "Elevation (m asl)", 
            style = "cont",
            palette = "-Spectral") +
  tm_layout(legend.outside = TRUE) +
tm_shape(vector) +
  tm_borders(col = "black", 
             lwd = 1) +
tm_shape(puntos) +
  tm_symbols(size = 0.2, col = "red") +
tm_add_legend(type = "symbol", col = "red",
              title = "Localizaciones importantes")

Mapa de isopletas

La creación de un mapa de isopletas requiere crearlas primero con la función tm_iso() y posteriormente cartografiarlas. La creación de isopletas se realiza con la función as.contour del paquete terra, siendo luego transformadas al formato sf. .

isopletas <- as.contour(mdt)
isopletas <- sf::st_as_sf(isopletas)

La representación cartográfica se realiza mediante la función tm_iso()

tm_shape(isopletas) +
  tm_iso()

Para mejorar la representación gráfica, es posible superponer las isolíneas al relieve, y además incorporar cierto sombreado para resaltar el relieve. Para todo ello se deben crear primero sendos objetos ráster que contienen la pendiente la pendiente (argumento slope) y de la orientación (argumento aspect). La unidad de medida son los radianes (obligatorios para la posterior función).

pendiente <- terrain(mdt, "slope", unit="radians")
orientacion <- terrain(mdt, "aspect", unit="radians")

Para calcular el sombreado del relieve, es necesario determinar el ángulo de elevación (argumento angle) y el ángulo (respecto al N) del sol, en ambos casos en grados.

sombreado <- shade(pendiente, orientacion, 40, 270)

Finalmente, se puede representar

tm_shape(sombreado) + 
  tm_raster(palette="-Greys", style="cont", legend.show=FALSE) +
tm_shape(mdt) + 
  tm_raster(alpha=.6, palette="cividis", style="cont", title="Elevation (m)") +
tm_compass(type="arrow", position=c(.15, .05)) +
tm_scale_bar(position = c(0.2, .005), text.size=.8) +
tm_layout(title = "Mapa de sombreado", title.size = 1.5, title.position = c("right", "top")) +
tm_credits("Datos de un MDT", position= c(.87, .03))

En esta variante, cambian los colores y se añaden las isopletas.

tm_shape(sombreado) +
    tm_grid() +
    tm_raster(palette = gray(0:100 / 100), n = 100, legend.show = FALSE) +
tm_shape(mdt) +
    tm_raster(alpha = 0.5, palette = terrain.colors(25),
              legend.show = FALSE) +
tm_shape(isopletas) +
    tm_lines(col = "white") +
    tm_text("level", col = "white")

MAPAS DE COROPLETAS

El mapa de coropletas es uno de los más utilizados para representar fenómenos discretos asociados a unidades de enumeración (provincias, países…), a las que se aplica una simbología de acuerdo con su valor. El valor de una determina variable dentro de cada unidad de enumeración o corograma se mantiene constante. Por ello, su propósito no es el de mostrar valores individuales concretos, sino obtener una idea de la distribución general de la variable cartografiada, particularmente comparando diferentes mapas entre sí. Este tipo de mapas se utilizan para representar datos discretos, normalmente tranformados en valores relativos.

La elaboración de un mapa de coropletas implica tomar una serie de decisiones que son críticas cara a los resultados; entre ellas citaremos el número y tamaño de los corogramas, el número de categorías en los que se clasifica la variable en cuestión y sus límites superior e inferior. Una vez tomadas estas decisiones, hay que elegir una simbología para la representación de cada categoría; se recomienda una variación en términos de claro-oscuro (el valor).

Evolución de una variable a través de diferentes mapas de coropletas
Evolución de una variable a través de diferentes mapas de coropletas

Una vez cargados en el directorio, la activación de ese paquete para cada sesión se realiza mediante la función ‘library’.

library(tidyverse)
library(sf)
library(tmap)
library(RColorBrewer)

En tmap hay dos formas de crear un mapa de coropletas. La más simple, que ya hemos visto, usa la función tm_polygons() con el nombre de la variable como argumento. El código de colores corresponde style = "pretty", que es el predeterminado cuando los rangos de las categorías no se definen establecen previamente.

tm_shape(poblacion) +
  tm_polygons("calificacion_escolar") + 
tm_layout(frame = FALSE)

La función tm_polygons() en realidad engloba otras dos funciones, tm_fill() y tm_borders().

Por ejemplo, utilizando la misma forma (pero sin variable), obtiene los contornos de los polígonos.

tm_shape(poblacion) +
  tm_borders()

De manera similar, obtenemos un mapa de coropletas sin los contornos de los polígonos cuando solo usamos el comando tm_fill.

tm_shape(poblacion) + 
  tm_fill("calificacion_escolar")

Cuando combinamos los dos argumentos, obtenemos el mismo mapa que con tm_polygons() (lo que ilustra cómo en R a menudo se puede obtener el mismo resultado de varias maneras diferentes).

tm_shape(poblacion) +
  tm_fill("calificacion_escolar") +
  tm_borders()

Paleta de colores

La gama de colores utilizada para representar la distribución espacial de una variable está determinada por la paleta de colores. La paleta es un argumento de la función tm_fill(). tmap incluye varias paletas; por ejemplo, palette = "Reds" produciría el siguiente mapa.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar", palette="Reds") +
  tm_borders()

Además de las paletas integradas en el paquete, se pueden crear rangos de colores personalizados especificando un vector con los colores deseados. Por ejemplo, si usamos c(“red”, “blue”), el espectro de color oscilaría desde el rojo a púrpura, luego a azul, con tonos intermedios.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",palette=c("red","blue")) +
  tm_borders()

Para imitar la escala divergente utilizada en muchos de los mapas de valores extremos, podemos insertar un nuevo color (“blanco”) entre el rojo y el azul.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",palette=c("red","white","blue")) +
  tm_borders()

Otra posibilidad para seleccionar una paleta de colores es elegir uno de los esquemas contenidos en el paquete RColorBrewer. Las paletas de este paquete se basan en la investigación de la cartógrafa Cynthia Brewer.

library(RColorBrewer)
display.brewer.all()

ColorBrewer hace una distinción entre:

  • Escalas secuenciales (que va de menor a mayor).

  • Escalas **divergentes* (para resaltar cómo los valores difieren de una tendencia central).

  • Escalas cualitativas (para variables categóricas).

Para cada escala, el paquete sugiere una serie de escalas de un solo tono y de varios tonos. Estas se denominan con un nombre (por ejemplo, la paleta “Reds” que usamos anteriormente es un ejemplo); su lista completa se encuentra en la documentación de RColorBrewer.

Hay dos comandos muy útiles en este paquete. Uno establece una paleta de colores especificando su nombre y el número de categorías deseadas. El resultado es un vector de caracteres con los códigos hexadecimales de los colores correspondientes. Por ejemplo, seleccionamos un esquema de color secuencial que va del azul al verde, como BuGn, mediante el comando brewer.pal, con el número de categorías (6) y el esquema como argumentos. El vector resultante contiene los códigos HEX para los colores.

pal <- brewer.pal(6,"BuGn")
display.brewer.pal(6,"BuGn")     # Ofrece una imagen de la paleta deseada
pal                              # Códigos hexagesimales de los colores

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",palette="BuGn") +
  tm_borders()

Leyenda

Hay muchas opciones para cambiar el formato de la leyenda a través del argumento legend.format(). Para personalizar el nombre de la variable en la leyenda se usa title dentro del argumento tm_fill().

tm_shape(poblacion) +
  tm_fill("calificacion_escolar", 
          title="Porcentaje de graduados") +
  tm_borders()

Otro aspecto importante de la leyenda es su ubicación. Esta se modifica a través de la función tm_layout(). Esta función tiene una gran cantidad de opciones, poseyendo subconjuntos especializados de funciones de diseño, centrados en aspectos específicos del mapa, como:

  • tm_legend()

  • tm_style()

  • tm_format().

Por defecto, tmap coloca la leyenda dentro del mapa. Cuando se necesita modificar esta disposición, el argumento legend.position() de la función tm_layout requiere añadir un vector con dos variables (cadenas) que determinan tanto la posición horizontal (“left”, “right” o “center”) como la posición vertical (“top”, “bottom”, or “center”). Por ejemplo, si quisiéramos mover la leyenda a la posición inferior derecha, usaríamos el siguiente conjunto de comandos.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Porcentaje de extranjeros en ciudad") +
  tm_borders() +
  tm_layout(legend.position = c("left", "bottom"))

También existe la opción de extraer la leyenda fuera del marco del mapa. Esto se logra estableciendo el argumento legend.outside = TRUE (el valor predeterminado es FALSE) y, opcionalmente, también especificando su posición mediante legend.outside.position() (puede tomar los valores “top”, “bottom”, “right”, and “left”). Por ejemplo, para colocar la leyenda afuera ya la derecha:

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Porcentaje de Extranjeros") + 
  tm_borders() +
  tm_layout(legend.outside = TRUE, legend.outside.position = "right")

También podemos personalizar el tamaño de la leyenda, su alineación, fuente, etc. Si bien no existe una forma de mostrar el número de observaciones en cada categoría, tmap tiene una opción para agregar un histograma a la leyenda. Esto se logra configurando legend.hist=TRUE dentro de la función tm_fill().

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Porcentaje de extranjeros",legend.hist=TRUE) + 
  tm_borders() +
  tm_layout(legend.outside = TRUE, legend.outside.position = "right")

Título

Otra funcionalidad de la función tm_layout() es establecer un título para el mapa y especificar su posición, tamaño, etc. Por ejemplo, podemos establecer title, title.size and title.position como en el ejemplo a continuación. Para no sobrecargar el mapa, también disminuimos ligeramente el tamaño de la fuente (0.8), y la colocamos en la esquina inferior derecha.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera")  +
  tm_borders() +
tm_layout(title = "Censo 2008", title.size = 0.8, title.position = c("right","bottom"))

Para que un título aparezca en la parte superior (o en la parte inferior) del mapa, en lugar de dentro (el valor predeterminado), debemos configurar el argumento main.title de la función tm_layout, con la main.title.position asociada, como se ilustra a continuación (con title.size establecido en 1.5 para tener una fuente más grande).

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Porcentaje")  +
  tm_borders() +
  tm_layout(main.title = "Población extranjera en Ciudad", 
            title.size = 1.5,
            main.title.position="center")

Opciones de borde

Hasta ahora no hemos especificado ningún argumento para la función tm_borders(). Las opciones comunes son el color de las líneas del borde (col), su grosor (lwd) y el tipo de línea (lty). El tipo de línea es una funcionalidad básica de R y se puede configurar especificando una cadena (“solid”, “dashed”, “dotted”, etc.) o el código interno (p. ej., 1 para sólida, 2 para discontinua, 3 para punteado). Para ilustrar esto, establecemos los bordes en azul, con un ancho de línea de 2.0 y usamos una línea punteada.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",
          title="Población extranjera")  +
  tm_borders(col="blue",lwd=2,lty=3)

Clasificación de intervalos

La relación más estrecha entre la cartografía (mapa de coropletas) y la estadística es la incorporación de intervalos de clase que convierten la variable continua en un pequeño número de clases, similar a un histograma. El uso de uno u otro método de clasificación puede revelar aspectos de la distribución espacial de una variable que no aparecen con los métodos estadísticos clásicos.

En tmap, la clasificación se selecciona mediante la opción style en tm_fill(). El valor predeterminado es pretty. Esta consiste en una función base R que calcula una secuencia de clases igualmente espaciadas. El número de clases o intervalos que resulta no es necesariamente igual a n (el número preferido de clases), lo que puede parecer confuso al principio.

Hay muchos tipos de métodos de clasificación disponibles en tmap, cada uno de los cuales corresponde a una función base de R o a un método contenido en la función classIntervals(). Los más conocidos son, probablemente, el mapa de cuantiles, el mapa de “natural breaks” y el “intervalos iguales”, aunque también es posible establecer clases personalizadas con sus propias etiquetas.

Mapa de cuantiles

Se obtiene un mapa de cuantiles configurando style=“quantile en tm_fill. El número de categorías se toma del argumento n, que tiene un valor predeterminado de 5: usando este valor predeterminado se genera un mapa de quintiles con cinco categorías (especificamos el tipo de mapa en el título a través de tm_layout()).

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera",style="quantile")  +
  tm_borders() +
  tm_layout(title = "Mapa de quintiles", title.position = c("right","top"))

Un mapa de cuartiles se crea especificando n = 4 (cuatro categorías) con style="quantile". El resto de los comandos son los mismos que antes.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera",n=4, style="quantile")  +
  tm_borders() +
  tm_layout(title = "Mapa de Cuartiles", title.position = c("right","top"))

Mapa con “Natural breaks”

Este tipo de mapa de coropletas se obtiene especificando style="jenks" en tm_fill().

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera",n=4, style="jenks")  +
tm_borders() +
tm_layout(title = "Mapa \n (método de Jenks)", title.position = c("right","top"))

Mapa con intervalos iguales

Se obtiene un mapa de intervalos iguales para cuatro categorías estableciendo n=4 y style =“equal”.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera",n=4,style="equal")  +
  tm_borders() +
  tm_layout(title = "Mapa de intervalos iguales", title.position = c("right","bottom"))

Mapa de desviaciones estándar

Para elaborar este tipo de mapa es necesario establecer como `style=“sd”.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Población extranjera",style="sd",palette="-RdBu")  +
  tm_borders() +
tm_layout(title = "Mapa de desviaciones estandar", title.position = c("right","bottom"))

Intervalos personalizados

Hasta ahora, tmap nos ha proporcionado una serie de métodos de clasificación automáticos. Es posible sustituir estos valores predeterminados incluyendo el argumento breaks en la función tm_fill.

En el ejemplo a continuación, establecemos 6 categorías; las etiquetas correspondientes a los valores de cada clase son el valor mínimo y el valor máximo. Para obtener n categorías se deben especificar n+1 elementos en la opción (sus valores deben estar en orden creciente). Un truco para establecer esos valores es calcular primero algunos estadísticos descripticos de esa variable.

summary(poblacion$calificacion_escolar)

De acuerdo con estos datos, podemos considerar como puntos de ruptura los valores 35, 55 y 65. Además, también debemos incluir un mínimo y un máximo, en este caso 11 y 89. Nuestro vector de marcas de clase es, por lo tanto, c(11, 35, 55, 65, 82). La paleta de calores utilizada es secuencial, y se denomina “YlOrBr” en ColorBrewer.

tm_shape(poblacion) +
  tm_fill("calificacion_escolar",title="Porcentaje de extranjeros",breaks=c(11, 35, 55, 65, 89), palette="YlOrBr")  +
  tm_borders() +
tm_layout(main.title = "Mapa de clases personalizado", main.title.position = "center")

Representación de variables discretas (Mapas de variables categóricas)

En tmap es necesario recurrir previamente a la función cut de R para crear las variables categóricas (cualitativas); posteriormente serán transformadas en factores para poder usar la opción style="cat" en “tm_fill()`. Si esto último se olvida, el mapa resultante sigue el ejemplo de una secuencia estandar.

Creación de las categorías

Este proceso se realiza en varios pasos. Primero creamos el objeto var a partir de la variable calificacion_escolar.

var <- poblacion[ , 4]  
str(var)

A continuación, podemos generar una secuencia de categorías en función de los cuantiles.

var$percentiles <- cut(var$calificacion_escolar,                                            
                       breaks = c(quantile(var$calificacion_escolar, probs = seq(0, 1, by = 0.20))),
                       labels = c(1, 2, 3, 4, 5),
                       right=FALSE,                                         
                      include.lowest=TRUE)                                 
var$percentiles

Finalmente, esta nueva variable será convertida en factor, y la añadiremos al dataframe original.

poblacion$percentiles <- as.factor(var$percentiles)

Mapa con valores

Para crear un mapa con la nueva variable se mantendrán las opciones anteriores, pero añadiremos style="cat"y la paleta de colores como set palette="Paired".

tm_shape(poblacion) +
  tm_fill("percentiles", style="cat",palette="Paired")  +
  tm_borders() +
  tm_layout(title = "Mapa con valores únicos", title.position = c("right","bottom"))

Centroides de polígonos.

La función st_centroid, parte del paquete sf, nos permite crear una capa de puntos que contiene todas las variables de la capa original.

poblacioncentroide <- st_centroid(poblacion)
summary(poblacioncentroide)

La posiblidad de suporponer capas del paquete tmap nos permite dibujar primero los límites de los distritos usando la función tm_borders. Sobre ella se dibuja la capa de centroides con la función tm_dots, que está especializada en el dibujo de símbolos. El dibujo incluye dos opciones: size=0.2 para incrementar el tamño de los puntos, y col=red para que su color sera rojo.

tm_shape(poblacion) +
  tm_borders() +
tm_shape(poblacioncentroide) +
  tm_dots(size=0.2,col="red")

Un examen del mapa releva que la localización de los centroides es incorrecta en polígonos no convexos. Para salvar esta capa como “shapefile” se usa la función st_write del paquete sf.

CARTOGRAMAS

Los cartogramas son una variante del mapa de coropletas, en los que se relacionan las cantidades de una variable asociada a las áreas de cada corograma, mediante la modificación del tamaño de éstos últimos. Esta distorsión de las superficie reales es la que proporciona la información de interés, convirtiendo cada corograma en un símbolo proporcional, el cual aumenta o disminuye en función de los valores correspondientes.

Es conveniente, antes de proceder a la realización del mapa, efectuar una comparación entre los datos a cartografiar y la base geográfica.

Si bien son visualmente impactantes, también son difíciles de leer sin un conocimiento del territorio representado, llegando a parece mapas incompletos.

En R, se incluye una implementación útil de diferentes tipos de cartogramas en el paquete cartogram. Específicamente, esto soporta el cartograma circular con la función cartogram_dorling(), así como cartogramas contiguos y no contiguos, con las funciones cartogram_cont() y cartogram_ncont().

library(cartogram)

Por ejemplo, a continuación se utiliza la variable extran para construir un cartograma circular

carto_dorling <- cartogram_dorling(mtq,                                      # Objeto gráfico como capa.
                                   "ingresos")                                    # Variables dentro de ese objeto gráfico
class(carto_dorling)

El resultado de las líneas de código anterior es un objeto sf que se puede cartografiar mediante los comandos habituales de tmap como tm_shape().

tm_shape(carto_dorling) +
  tm_fill("ingresos") +
  tm_borders()

De forma adicional, es posible elaborar un cartograma contiguo, que extiende los límites de los polígonos de modo que las unidades espaciales permanezcan contiguas, pero tomen un área proporcional al valor de la variable de interés

carto_cont <- cartogram_cont(mtq,"ingresos")

tm_shape(carto_cont) +
  tm_fill("ingresos") +
  tm_borders()

Finalmente, podemos dibujar un cartograma no-contiguo, que muestra las unidades espaciales flotando en el “espacio”

carto.ncont <- cartogram_ncont(mtq,"ingresos")
tm_shape(carto.ncont) +
  tm_fill("ingresos") +
  tm_borders()

📝 ACTIVIDAD DE EVALUACIÓN CONTINUA:

#wv_counties <- st_read("C:/Maxwell_Data/Dropbox/Teaching_WVU/WVAGP/wvagp_webgis/county_boundaries.shp")
wv_cont <- cartogram_cont(x=wv_counties, weight="POP2000")
wv_ncont <- cartogram_ncont(x=wv_counties, weight="POP2000")
tm_shape(wv_counties)+
    tm_polygons(col="POP2000")
tm_shape(wv_cont)+
    tm_polygons(col="tan")
tm_shape(wv_ncont)+
    tm_polygons(col="tan")

MAPAS DE FLUJO

Son mapas que muestran movimientos lineales entre puntos del territorio, en los que el ancho de las líneas es proporcional a las cantidades representadas; el símbolo más utilizado es la flecha, que indica la dirección y sentido del flujo. Se aplican a datos de tipo nominal, ordinal o de intervalo, tanto en valores absolutos como relativos. Las leyendas son variadas, por ejemplo en forma de escalones (línea reglada), con valores específicos o valores de intervalo.

El paquete tmap no dispone de una función específica para la elaboración de este tipo de mapas. Por ello recurriremos al paquete cartography, que sí dispone de funciones adecuadas para la representación de estos flujos. Este paquete trabaja con objetos sf.

library(cartography)

A continuación se cargan los datos para crear el diagrama de flujo.

str(mob)

Seleccionamos aquellas entidades cuyo estatus administrativo se el de Prefecture o Sub-prefecture.

mob <- mob[mob$sj != "Simple municipality",]

Con la función getLinkLayer se crea un objeto sf.

mtq_mob <- getLinkLayer(x = mtq, 
                        xid = "id", 
                        df = mob, 
                        dfid = c("i","j"))

Se establece el color del fondo del mapa

par(bg="grey25")

Por último, se representan las entidades municipales y las conexiones

plot(st_geometry(mtq), 
     col = "grey13", 
     border = "grey25", 
     bg = "grey75", 
     lwd = 0.5)

gradLinkTypoLayer(x = mtq_mob, 
                  xid = c("i", "j"), 
                  df = mob, 
                  dfid = c("i","j"), 
                  var = "fij", 
                  breaks = c( 100,  500, 1200, 2500, 4679.0),
                  lwd = c(1,4,8,16), 
                  legend.var.pos = "left",
                  legend.var.title.txt = "Núm. \n viajeros",
                  var2 = "sj", 
                  col = c("grey85", "red4"), 
                  legend.var2.title.txt = "Workplace",
                  legend.var2.pos = "topright") 

layoutLayer(title = "Commuting to Prefectures in Martinique", 
            sources = "Fuente: Insee e IGN, 2018",  
            author = paste0("paquete cartografía", packageVersion("cartography")), 
            frame = FALSE, col = "grey25", coltitle = "white",
            tabtitle = TRUE)

COLOR AMARILLO:

Existe un paquete específico para la representación de flujos entre localidades, denominado flowmpaper que puede consultarse en internet.

MAPA DE DISCONTINUIDADES

Los mapas de discontinuidades se basan en la variación de un fenómeno entre unidades contiguas. Este tipo de representación se centra en las discontinuidades espaciales. La intensidad de la discontinuidad se expresa mediante el grosor de los bordes.

getBorders() se utiliza para construir un objeto espacial de fronteras entre unidades. Cada frontera resultante contiene los ids de sus dos unidades vecinas. Es posible complementar estas fronteras con getOuterBorders() para calcular fronteras entre unidades no contiguas (por ejemplo, fronteras marítimas).

discLayer() calcula y muestra las discontinuidades, el ancho de las líneas refleja la relación o la diferencia absoluta entre los valores de un indicador en dos unidades vecinas.

library(cartography)

En primer lugar, calculamos la densidad de la población (inhab./km2) usando la función sf::st_area().

mtq$POPDENS <- as.numeric(1e6 * mtq$pob / st_area(mtq))

A continuación, aplicamos la función getBorders()

mtq_contig <- getBorders(mtq)

Finalmente, representamos gráficamente la geometría (unidades administrativas) del objeto mtq (sólo se dibuja el color de fondo), una capa con la densidad de la población usando cierto número de intervalos, y las discontinuidades entre esas unidades administrativas.

plot(st_geometry(mtq), 
     col = NA, 
     border = NA, 
     bg = "lightblue1", 
     xlim = c(690574, 745940))

choroLayer(x = mtq, 
           var = "ingresos",
           breaks = c(min(mtq$ingresos), seq(13000, 21000, 2000), max(mtq$ingresos)),
           col = carto.pal("green.pal", 6),
           border = "white", 
           lwd = 0.5, 
           legend.pos = "topright", 
           legend.title.txt = "Ingreso Mediano\n(euros)",
           add = TRUE)

discLayer(x = mtq_contig, 
          df = mtq, 
          var = "ingresos",
          type = "rel", 
          method = "geom", 
          nclass = 3,
          threshold = 0.4,
          sizemin = 0.7, 
          sizemax = 6, 
          col = "red4",
          legend.values.rnd = 1, 
          legend.title.txt = "Discontinuidades\nRelativas", 
          legend.pos = "left",
          add = TRUE)

layoutLayer(title = "Desigualdades económicas en Martinica, 2015", 
            author =  paste0("paquete cartography ", packageVersion("cartography")),
            sources = "Fuente: Insee y IGN, 2018",
            frame = FALSE, scale = 5, tabtitle = TRUE,theme = "grey.pal")

north(pos = "topleft")                               # Flecha del Norte

COMBINACIÓN DE MAPAS

También podemos hacer que el shapefile poligonal muestre una de nuestras variables censales como un mapa de coropletas como se muestra a continuación. En este ejemplo también hemos añadido algunos parámetros más dentro de la función tm_bubbles() para crear bordes finos alrededor de los puntos.

tm_shape(poblacion) + 
  tm_fill("calificacion_escolar", 
          palette = "Reds", 
          style = "quantile", 
          title = "% graduados") +
  tm_borders(alpha=.4) +
tm_shape(casas) + 
  tm_bubbles(size = "precio", 
           col = "precio", 
           palette = "Blues", 
           style = "quantile", 
           legend.size.show = FALSE, 
           title.col = "Precio de la vivienda (€)", 
           border.col = "black", 
           border.lwd = 0.1, 
           border.alpha = 0.1) +
tm_layout(legend.text.size = 0.65, 
          legend.title.size = 0.8, 
          frame = FALSE)

Guardar un mapa como un archivo

Hasta ahora, solo hemos trazado el mapa en la pantalla o un widget interactivo. Para guardar el mapa como salida, primero asignamos el resultado de una serie de comandos tmap a una variable (un objeto).

A partir de ahí, podemos guardar este objeto por medio de la función tmap_save. Esta función toma el objeto del mapa como el argumento tm y el nombre del archivo de salida como el nombre del archivo del argumento.

La salida predeterminada es un archivo png. Otros formatos se obtienen al incluir la extensión de archivo adecuada.

Además, hay muchas otras opciones, como especificar la altura, el ancho y la resolución (ppp). Por ejemplo, asignamos nuestro mapa predeterminado rudimentario a la variable mimapa y luego lo guardamos en el archivo mimapa.png, que es guardado en el directorio de trabajo.

mimapa <- tm_shape(poblacion) +
  tm_fill("pob_nacional") +
  tm_borders()

tmap_save(tm = mimapa, filename = "mimapa.png")

Guardar el entorno de trabajo.

Existen varias posibilidad a la hora de guardar toda la información creada. Se puede exportar todo el espacio de trabajo desde R con la función save.image; el archivo resultante tiene la extensión RData.

save.image(file = "Objetos_R.RData")

En ocasiones, si sólo se requiere salvar algunos objetos concretos, se pueden especificar separándolos por comas con la función save.