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:
Mapa de puntos
Mapa de isolíneas.
Mapa de coropletas.
Cartogramas.
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:
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:
**id: variable cualitativa (carácter), identificador del municipio.
status: variable cualitativa (carácter), tipo de municipio.
nombre: variable cualitativa (carácter), nombre de cada municipio.
pob: variable cuantitativa, población de cada municipio.
ingresos: variable cuantitativa, ingreso mediano.
desempleados: variable cuantitativa, número de demandantes de empleo.
activos: variable cuantitativa, número de personas con empleo.
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
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
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:
En el primer caso, los símbolos proporcionales corresponderán al valor de una variable localizada en puntos del territorio, caracterizadas por coordenadas geográficas o proyectadas.
En el segundo caso, los símbolos proporcionales tienen un significado similar al del mapa de coropletas, ya que reflehan el valor de una variable sobre un polígono (por ejemplo, una provincia, un estado etc…).
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
).
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
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()
.
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")
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")
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).
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()
.
tm_fill()
controla el contenido de los polígonos
(color, clasificación, etc.)
tm_borders()
hace lo mismo con los contornos de los
polígonos.
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()
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()
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")
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")
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)
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.
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"))
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"))
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"))
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"))
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")
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.
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)
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"))
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.
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")
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.
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
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)
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")
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
.