4. Mapas

Hay muchas maneras de hacer un mapa con plotly, cada una con sus puntos fuertes y débiles. En términos generales, los enfoques se dividen en dos categorías: integrados o personalizados. Los mapas integrados aprovechan el soporte integrado de plotly.js para renderizar una capa de mapa base. Actualmente hay dos formas de hacer mapas integrados: a través de Mapbox o a través de un mapa base integrado con d3.js. El enfoque integrado es conveniente si necesitas un mapa rápido y no necesitas necesariamente representaciones sofisticadas de objetos geoespaciales. Por otro lado, el enfoque de mapas personalizados ofrece un control total, ya que tú proporcionas toda la información necesaria para representar el/los objeto(s) geoespacial(es). El apartado 4.2 trata de la elaboración de mapas sofisticados (por ejemplo, cartogramas) utilizando el paquete sf R, pero también es posible elaborar mapas personalizados mediante otras herramientas de geoinformática (por ejemplo, sp, ggmap, etc.).

Vale la pena señalar que plotly pretende ser una biblioteca de visualización de propósito general, y por lo tanto, no pretende ser el más completo conjunto de herramientas de visualización geo-espacial. Dicho esto, hay beneficios en el uso de mapas basados en plotly, ya que las API de mapeo son muy similares al resto de plotly, y se puede aprovechar el ecosistema plotly más grande (por ejemplo, la vinculación de vistas del lado del cliente como la Figura 16.23). Sin embargo, si te encuentras con limitaciones con la funcionalidad de mapeo de plotly, hay un conjunto muy rico de herramientas para la visualización geoespacial interactiva en R, incluyendo pero no limitado a: leaflet, mapview, mapedit, tmap, y mapdeck (Robin Lovelace 2019).

4.1 Mapas integrados

4.1.1 Panorama general

Si tiene datos de latitud/longitud bastante simples y quiere hacer un mapa rápido, puede probar una de las opciones de mapeo integradas en plotly (por ejemplo, plot_mapbox() y plot_geo()). En general, puede tratar estas funciones constructoras como un reemplazo de plot_ly() y obtener un mapa base dinámico detrás de sus datos. Además, todas las capas basadas en dispersión sobre las que aprendimos en la Sección 3 funcionan como cabría esperar con plot_ly().12 Por ejemplo, la Figura 4.1 utiliza plot_mapbox() y add_markers() para crear un gráfico de burbujas:

Sys.setenv('MAPBOX_TOKEN' = 'pk.eyJ1IjoiamFwYTE4IiwiYSI6ImNsZnByaW5sbjBkdzQzcW9iamF0ZDZlYWMifQ.COe4EHrbH88k8UQ2N_yS3g')
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
plotly::plot_mapbox(maps::canada.cities)     %>%
  plotly::add_markers(
    x = ~long, 
    y = ~lat, 
    size = ~pop, 
    color = ~country.etc,
    colors = "Accent",
    text = ~paste(name, pop),
    hoverinfo = "text"
  )
## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.
## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors

El estilo del mapa base de Mapbox se controla a través del atributo layout.mapbox.style. El paquete plotly viene con soporte para 7 estilos diferentes, pero también puedes proporcionar una URL personalizada a un estilo mapbox personalizado. Para obtener todos los nombres de estilo de mapa base pre-empaquetados, puedes tomarlos del “the official plotly.js() schema:

library(plotly)
## Loading required package: ggplot2
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(listviewer)

styles <- schema()$layout$layoutAttributes$mapbox$style$values
styles
##  [1] "basic"             "streets"           "outdoors"         
##  [4] "light"             "dark"              "satellite"        
##  [7] "satellite-streets" "carto-darkmatter"  "carto-positron"   
## [10] "open-street-map"   "stamen-terrain"    "stamen-toner"     
## [13] "stamen-watercolor" "white-bg"
#>  [1] "basic"             "streets"          
#>  [3] "outdoors"          "light"            
#>  [5] "dark"              "satellite"        
#>  [7] "satellite-streets" "open-street-map"  
#>  [9] "white-bg"          "carto-positron"   
#> [11] "carto-darkmatter"  "stamen-terrain"   
#> [13] "stamen-toner"      "stamen-watercolor"

Cualquiera de estos valores puede utilizarse para un estilo mapbox. La figura 4.2 muestra el mapa base de imágenes terrestres por satélite.

layout(
  plot_mapbox(), 
  mapbox = list(style = "satellite")
)
## No scattermapbox mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

La figura 4.3 muestra cómo crear un menú desplegable plotly.js integrado para controlar el estilo del mapa base a través del atributo layout.updatemenus. La idea detrás de un menú desplegable plotly.js integrado es proporcionar una lista de botones (es decir, elementos de menú) donde cada botón invoca un método plotly.js con algunos argumentos. En este caso, cada botón utiliza el método relayout para modificar el atributo layout.mapbox.style.

style_buttons <- lapply(styles, function(s) {
  list(
    label = s, 
    method = "relayout", 
    args = list("mapbox.style", s)
  )
})
layout(
  plot_mapbox(), 
  mapbox = list(style = "dark"),
  updatemenus = list(
    list(y = 0.8, buttons = style_buttons)
  )
)
## No scattermapbox mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

La otra solución cartográfica integrada en plotly es plot_geo(). Comparada con plot_mapbox(), esta aproximación tiene soporte para diferentes proyecciones de mapeo, pero la estilización del mapa base es limitada y puede ser más engorrosa. La figura 4.4 muestra el uso de plot_geo() junto con add_markers() y add_segments() para visualizar rutas de vuelo dentro de Estados Unidos. Mientras que plot_mapbox() está fijado a una proyección mercator, el constructor plot_geo() tiene un puñado de diferentes proyecciones disponibles, incluyendo la proyección ortográfica que da la ilusión del globo 3D.

library(plotly)
library(dplyr)
# airport locations
air <- read.csv(
  'https://plotly-r.com/data-raw/airport_locations.csv'
)
# flights between airports
flights <- read.csv(
  'https://plotly-r.com/data-raw/flight_paths.csv'
)
flights$id <- seq_len(nrow(flights))

# map projection
geo <- list(
  projection = list(
    type = 'orthographic',
    rotation = list(lon = -100, lat = 40, roll = 0)
  ),
  showland = TRUE,
  landcolor = toRGB("gray95"),
  countrycolor = toRGB("gray80")
)

plot_geo(color = I("pink")) %>%
  add_markers(
    data = air, x = ~long, y = ~lat, text = ~airport,
    size = ~cnt, hoverinfo = "text", alpha = 0.5
  ) %>%
  add_segments(
    data = group_by(flights, id),
    x = ~start_lon, xend = ~end_lon,
    y = ~start_lat, yend = ~end_lat,
    alpha = 0.3, size = I(1), hoverinfo = "none"
  ) %>%
  layout(geo = geo, showlegend = FALSE)
## Warning: `line.width` does not currently support multiple values.

Algo bueno de plot_geo() es que proyecta automáticamente las geometrías en el sistema de coordenadas adecuado definido por la proyección del mapa. Por ejemplo, en la Figura 4.5 el segmento de línea simple es recto cuando se utiliza plot_mapbox() pero curvo cuando se utiliza plot_geo(). Es posible conseguir el mismo efecto utilizando plot_ly() o plot_mapbox(), pero los datos relevantes del marcador/línea/polígono tienen que ponerse en una estructura de datos sf antes de renderizar (ver Sección 4.2.1 para más detalles).

map1 <- plot_mapbox() %>% 
  add_segments(x = -100, xend = -50, y = 50, yend = 75) %>%
  layout(
    mapbox = list(
      zoom = 0,
      center = list(lat = 65, lon = -75)
    )
  )

map2 <- plot_geo() %>% 
  add_segments(x = -100, xend = -50, y = 50, yend = 75) %>%
  layout(geo = list(projection = list(type = "mercator")))

library(htmltools)
browsable(tagList(map1, map2))

4.1.2 Choropleths

Además de las trazas de dispersión, ambas soluciones de cartografía integrada (es decir, plot_mapbox() y plot_geo()) tienen un tipo de traza de coropleta optimizado (es decir, los tipos choroplethmapbox y choropleth trace). Comparativamente hablando, choroplethmapbox es más potente porque puede especificar completamente la colección de características utilizando GeoJSON, pero el trazado choropleth puede ser un poco más fácil de usar si se ajusta a su caso de uso.

La Figura 4.6 muestra la densidad de población de EE.UU. a través del trazado coropleto utilizando los datos estatales de EE.UU. del paquete datasets (R Core Team 2016). Con solo proporcionar un atributo z, los objetos plotly_geo() intentarán crear un choropleth, pero también tendrá que proporcionar ubicaciones y un locationmode. Vale la pena señalar que el modo de ubicación se limita actualmente a países y estados de EE.UU., por lo que si necesita una unidad geográfica diferente (por ejemplo, condados, municipios, etc.), debe utilizar el tipo de traza choroplethmapbox y/o utilizar un enfoque de mapeo “personalizado” como se discute en la Sección 4.2.

library(plotly)
density <- state.x77[, "Population"] / state.x77[, "Area"]

g <- list(
  scope = 'usa',
  projection = list(type = 'albers usa'),
  lakecolor = 'white'
)

plot_geo() %>%
  plotly::add_trace(
    z = ~density, text = state.name, span = I(0),
    locations = state.abb, locationmode = 'USA-states'
  ) %>%
  layout(geo = g)

Choroplethmapbox es más flexible que choropleth porque usted proporciona su propia definición GeoJSON del choropleth a través del atributo geojson. Actualmente, este atributo debe ser una URL que apunte a un archivo geojson. Además, la ubicación debe apuntar a un atributo id de nivel superior de cada característica dentro del archivo geojson. La Figura 4.7 muestra cómo podríamos visualizar la misma información que en la Figura 4.6, pero esta vez utilizando choroplethmapbox.

plot_ly() %>%
  add_trace(
    type = "choroplethmapbox",
    # See how this GeoJSON URL was generated at
    # https://plotly-r.com/data-raw/us-states.R
    geojson = paste(c(
      "https://gist.githubusercontent.com/cpsievert/",
      "7cdcb444fb2670bd2767d349379ae886/raw/",
      "cf5631bfd2e385891bb0a9788a179d7f023bf6c8/", 
      "us-states.json"
    ), collapse = ""),
    locations = row.names(state.x77),
    z = state.x77[, "Population"] / state.x77[, "Area"],
    span = I(0)
  ) %>%
  layout(
    mapbox = list(
      style = "light",
      zoom = 4,
      center = list(lon = -98.58, lat = 39.82)
    )
  ) %>%
  config(
    mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN"),
    # Workaround to make sure image download uses full container
    # size https://github.com/plotly/plotly.js/pull/3746
    toImageButtonOptions = list(
      format = "svg", 
      width = NULL, 
      height = NULL
    )
  )

Las figuras 4.6 y 4.7 no son una forma ideal de visualizar la población estatal desde el punto de vista de la percepción gráfica. Normalmente utilizamos el color en las coropletas para codificar una variable numérica (por ejemplo, el PIB, las exportaciones netas, la nota media del SAT, etc.) y el ojo percibe de forma natural el área que cubre un color concreto como proporcional a su efecto global. Esto acaba siendo engañoso, ya que el área que cubre el color no suele tener ninguna relación razonable con los datos codificados por el color. Un ejemplo clásico de este efecto engañoso es el de los mapas de las elecciones estadounidenses: la proporción de rojo y azul no es representativa del voto popular global (Newman, 2016).

4.2 Mapas Personalizados

4.2.1 Caracteristicas simples (sf)

El paquete sf R es un enfoque moderno para trabajar con estructuras de datos geoespaciales basadas en principios de datos ordenados (Pebesma 2018; Wickham 2014b). La idea clave detrás de sf es que almacena geometrías geoespaciales en una lista-columna de un marco de datos. Esto permite que cada fila represente la unidad real de observación/interés -ya sea un polígono, un multipolígono, un punto, una línea o incluso una colección de estas características- y, como resultado, funciona a la perfección dentro de flujos de trabajo ordenados más grandes.14 El paquete sf en sí no proporciona realmente datos geoespaciales, sino que proporciona el marco y las utilidades para almacenar y calcular sobre estructuras de datos geoespaciales de una manera opinada.

Existen numerosos paquetes para acceder a datos geoespaciales como simples estructuras de datos de características. Un par de ejemplos notables incluyen rnaturalearth y USAboundaries. El paquete rnaturalearth es mejor para obtener cualquier dato cartográfico del mundo a través de una API proporcionada por https://www.naturalearthdata.com/ (South 2017). El paquete USAboundaries es estupendo para obtener datos cartográficos de Estados Unidos en cualquier momento de la historia (Mullen y Bratt 2018). En realidad, no importa qué herramienta utilices para obtener o crear un objeto sf: una vez que lo tengas, plot_ly() sabe cómo renderizarlo:

library(rnaturalearth)
world <- ne_countries(returnclass = "sf")
class(world)
## [1] "sf"         "data.frame"
#> [1] "sf"    "data.frame"
plotly::plot_ly(world, color = I("gray90"), stroke = I("black"), span = I(1))
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter

¿Cómo sabe plot_ly() cómo representar los países? Porque las características geoespaciales están codificadas en una lista-columna especial (geometría). Además, los metadatos sobre la estructura geoespacial se conservan como atributos especiales de los datos. La figura 4.9 amplía el método de impresión de sf a marcos de datos para demostrar que toda la información necesaria para representar los países (es decir, los polígonos) de la figura 4.8 está contenida en el marco de datos mundo. Observe también que sf proporciona métodos dplyr especiales para esta clase especial de marco de datos, de modo que pueda tratar las manipulaciones de datos como si se tratara de una estructura de datos “ordenada”. Una cosa sobre este método es que la columna especial ‘geometría’ siempre se mantiene - si tratamos de seleccionar sólo la columna nombre, entonces obtenemos tanto el nombre como la geometría.

1

En realidad hay 4 formas diferentes de representar objetos sf con plotly: plot_ly(), plot_mapbox(), plot_geo(), y a través de geom_sf() de ggplot2. Estas funciones renderizan múltiples polígonos utilizando una única traza por defecto, lo cual es rápido, pero puede que desee aprovechar la flexibilidad añadida de múltiples trazas. Por ejemplo, una traza dada sólo puede tener un color de relleno, por lo que es imposible renderizar múltiples polígonos con diferentes colores utilizando una sola traza. Por esta razón, si desea variar el color de múltiples polígonos, asegúrese de que los divide por un identificador único (por ejemplo, nombre), como se hace en la Figura 4.10. Tenga en cuenta que, como se ha comentado para los gráficos de líneas en la Figura 3.2, el uso de múltiples trazas añade automáticamente la posibilidad de filtrar el nombre a través de las entradas de la leyenda.

library(rnaturalearth)
canada <- ne_states(country = "Canada", returnclass = "sf")
plotly::plot_ly(canada, split = ~name, color = ~provnum_ne)
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter

Otra característica importante para los mapas que pueden requerir la división de varios polígonos en varias trazas es la posibilidad de mostrar un hover-on-fill diferente para cada polígono. Al proporcionar un texto único para cada polígono y especificar hoveron=‘fills’, la información sobre herramientas se vincula al relleno del trazado (en lugar de mostrarse en cada punto del polígono).

plotly::plot_ly(
  canada, 
  split = ~name, 
  color = I("gray90"), 
  text = ~paste(name, "is \n province number", provnum_ne),
  hoveron = "fills",
  hoverinfo = "text",
  showlegend = FALSE
)
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter

Aunque los enfoques cartográficos integrados (plot_mapbox() y plot_geo()) pueden representar objetos sf, los enfoques cartográficos personalizados (plot_ly() y geom_sf()) son más flexibles porque permiten cualquier proyección cartográfica bien definida. Trabajar con proyecciones cartográficas y comprenderlas puede resultar intimidante para un cartógrafo ocasional. Afortunadamente, existen buenos recursos para buscar proyecciones cartográficas en una interfaz sencilla, como http://spatialreference.org/. A través de este sitio web, se pueden buscar las proyecciones deseables para una determinada porción del globo y extraer comandos para proyectar sus objetos geoespaciales en esa proyección. Una forma de realizar la proyección es suministrar el comando PROJ4 pertinente a la función st_transform() en sf (colaboradores de PROJ 2018).

a

Algunos objetos geoespaciales tienen una resolución innecesariamente alta para una visualización determinada. En estos casos, es posible que desee considerar la simplificación del objeto geoespacial para mejorar la velocidad del código R y la capacidad de respuesta de la visualización. Por ejemplo, podríamos recrear la Figura 4.8 con una resolución mucho mayor especificando scale = “large” en ne_countries() esto nos da un objeto sf con más de 50 veces más coordenadas espaciales que la escala por defecto. La mayor resolución nos permite ampliar mejor las regiones geoespaciales más complejas, pero permite que el código R sea más lento, que los archivos HTML sean más grandes y que la capacidad de respuesta sea más lenta. Sievert (2018b) explora esta cuestión en mayor profundidad y demuestra cómo utilizar la función st_simplify() de sf para simplificar las características antes de trazarlas.

library(rnaturalearth)
sum(rapply(world$geometry, nrow))
## [1] 10654
#> [1] 10586

world_large <- ne_countries(scale = "large", returnclass = "sf")
sum(rapply(world_large$geometry, nrow))
## [1] 548471
#> [1] 548121

De forma análoga a la discusión en torno a 3.2, vale la pena ser consciente de las ventajas y desventajas que implica la representación de gráficos plotly utilizando una o varias trazas, y saber cómo aprovechar uno u otro enfoque. Específicamente, por defecto, plotly intenta renderizar todas las características simples en una sola traza, lo cual es eficiente, pero no tiene mucha interactividad.

4.2.2 Cartogramas

Los cartogramas distorsionan el tamaño de los polígonos geoespaciales para codificar una variable numérica distinta del tamaño del terreno. Existen numerosos tipos de cartogramas y se suelen clasificar por su capacidad para conservar la forma y mantener las regiones contiguas. Se ha demostrado que los cartogramas son un enfoque eficaz tanto para codificar como para enseñar sobre datos geoespaciales, aunque los efectos ciertamente varían según el tipo de cartograma (Nusrat S, Alam MJ, Kobourov S. 2018). El paquete R cartogram proporciona una interfaz para varios algoritmos populares de cartograma (Jeworutzki 2018). Varios otros paquetes de R proporcionan algoritmos de cartograma, pero lo bueno de cartogram es que todas las funciones pueden tomar un objeto sf (o sp) como entrada y devolver un objeto sf. Esto hace que sea increíblemente fácil pasar de objetos espaciales sin procesar a objetos transformados y a visuales. La figura 4.13 muestra un cartograma de área continua de la población de EE.UU. en 2014 utilizando un algoritmo de distorsión de hoja de goma de James A. Dougenik, Nicholas R. Chrisman, Duane R. Niemeyer (1985).

b

La Figura 4.14 muestra un cartograma Dorling no continuo de la población de EE.UU. en 2014 de Dorling, D (1996). Este cartograma no intenta conservar la forma de los polígonos (es decir, los estados), sino que utiliza círculos para representar cada objeto geoespacial y codifica la variable de interés (es decir, la población) utilizando el área del círculo.

c

La Figura 4.15 muestra un cartograma no continuo de la población de EE.UU. en 2014 de Olson, J. M. (1976). A diferencia del cartograma de Dorling, este enfoque conserva la forma de los polígonos. La implementación de la Figura 4.15 consiste simplemente en tomar la implementación de la Figura 4.14 y cambiar cartogram_dorling() por cartogram_ncont().

d

Una clase popular de cartogramas contiguos que no conservan la forma se denominan a veces cartogramas en mosaico (también conocidos como tilegrams). En el momento de escribir esto, no parece haber un gran paquete R para calcular tilegrams, pero Pitch Interactive proporciona un buen servicio web donde se pueden generar tilegrams a partir de datos existentes o personalizados https://pitchinteractiveinc.github.io/tilegrams/. Además, el servicio permite descargar un archivo TopoJSON del tilegrama generado, que podemos leer en R y convertir en un objeto sf a través de geojsonio (Chamberlain y Teucher 2018). La Figura 4.16 muestra un tilegrama de la población de Estados Unidos en 2016 exportado directamente desde el servicio web gratuito de Pitch.

e

Referencias

Chamberlain, Scott, and Andy Teucher. 2018. Geojsonio: Convert Data from and to ‘Geojson’ or ‘Topojson’. https://CRAN.R-project.org/package=geojsonio.

Dorling, D. 1996. “Area Cartograms: Their Use and Creation.” Concepts and Techniques in Modern Geography (CATMOG).

Hijmans, Robert J. 2019. Raster: Geographic Data Analysis and Modeling. https://CRAN.R-project.org/package=raster.

James A. Dougenik, Nicholas R. Chrisman, Duane R. Niemeyer. 1985. “An Algorithm to Construct Continuous Area Cartograms.” The Professional Geographer.

Jeworutzki, Sebastian. 2018. Cartogram: Create Cartograms with R. https://CRAN.R-project.org/package=cartogram.

Mullen, Lincoln A., and Jordan Bratt. 2018. “USAboundaries: Historical and Contemporary Boundaries of the United States of America.” Journal of Open Source Software 3 (23): 314. https://doi.org/10.21105/joss.00314.

Newman, Mark. 2016. “Maps of the 2016 Us Presidential Election Results.” Blog. http://www-personal.umich.edu/~mejn/election/2016/.

Nusrat S, Alam MJ, Kobourov S. 2018. “Evaluating Cartogram Effectiveness.” IEEE Trans Vis Comput Graph. https://doi.org/10.1109/TVCG.2016.2642109.

Olson, J. M. 1976. “Noncontiguous Area Cartograms.” The Professional Geographer.

Pebesma, Edzer. 2018. Sf: Simple Features for R. https://CRAN.R-project.org/package=sf.

Pebesma, Edzer J., and Roger S. Bivand. 2005. “Classes and Methods for Spatial Data in R.” R News 5 (2): 9–13. https://CRAN.R-project.org/doc/Rnews/.

PROJ contributors. 2018. PROJ Coordinate Transformation Software Library. Open Source Geospatial Foundation. https://proj4.org/.

R Core Team. 2016. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.

Robin Lovelace, Jannes Muenchow, Jakub Nowosad. 2019. Geocomputation with R. Chapman and Hall/CRC.

Sievert, Carson. 2018b. “Learning from and Improving Upon Ggplotly Conversions.” Blog. https://blog.cpsievert.me/2018/01/30/learning-improving-ggplotly-geom-sf/.

South, Andy. 2017. Rnaturalearth: World Map Data from Natural Earth. https://CRAN.R-project.org/package=rnaturalearth.

Wickham, Hadley. 2014b. “Tidy Data.” The Journal of Statistical Software 59 (10). http://www.jstatsoft.org/v59/i10/.