Картирование Южной Америки с помощью R Погружение в гео-визуализацию

Картирование Южной Америки с помощью R и гео-визуализации

Фото Александра Шиммека на Unsplash

Так вот, вы тот род дата-ученых и любитель писать об искусственном общем интеллекте, который любит карты и географию с детства. Вы ищете хорошую тему для своей последующей работы с графиками и, конечно же, картами, когда понимаете, что официальное статистическое агентство вашей страны, Бразилии, опубликовало самые свежие данные переписи населения. Почему бы и нет? Почему бы не сравнить Бразилию с ее соседями в Южной Америке? Это может быть простая задача с использованием R и всех его хороших пакетов. Давайте сделаем это.

Минуту спустя после этого решения осознается, что эта простая задача на самом деле является геройским путешествием со всеми его элементами, такими как поиск наиболее подходящего набора данных с файлами формы, отсутствие информации, взаимодействие файлов формы, математические расчеты широты и долготы, культурные различия в географических понятиях и даже геополитические вопросы, такие как понимание того, как правильно разместить карту и данные французских заморских территорий в Южной Америке.

В следующих параграфах объясняется один из возможных путей для представления демографической информации на ограниченной части карты мира. Описанный ниже пошаговый подход может быть полезен всем заинтересованным в международном сравнении с геовизуализацией, даже если целью является сравнение доступа к воде между африканскими странами или уровня ожирения в Северной Америке.

Пачамама

Давайте начнем с общей картины: версия mapa-mundi на R. См. изображение и код ниже.

Mapa Mundi: Изображение от автора
library(readxl)library(geobr)library(tidyverse)library(sf)library(spData)library(ggrepel)data("world")#mapa mundiworld %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  scale_fill_continuous_sequential(palette= "Heat 2" )+  theme_void() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("População em milhões de habitantes", 10)  )

Я использую пакет {spData} в качестве справочника для фрейма данных с геометрической информацией для файлов формы территорий по всей планете. Функция aes использует информацию о населении для заполнения форм. Как мы знаем, Китай и Индия являются самыми населенными странами в мире с более чем 1 миллиардом человек каждая. Цвета тепла показывают контраст с другими странами. Большинство последовательных цветов слабы. Мы едва можем различить градиент цветов на картинке. Логарифм – это лучшая альтернатива, если вы хотите увидеть лучшее распределение цветов. См. ниже.

Mapa mundi с логарифмическим масштабом. Изображение от автора
world %>%  ggplot() +  geom_sf(aes(fill=pop)) +  scale_fill_continuous_sequential(palette= "Heat 2", trans= "log2" )+  theme_void() +  theme(    panel.background = element_rect(fill="#0077be"),    legend.position = "none"  )

В коде вы можете увидеть преобразование логарифма в функции scale_fill_continuous_sequential.

В структуре фрейма данных world есть столбец Continent. Поэтому очевидно фильтровать данные, используя этот столбец, чтобы получить карту Южной Америки. См. код и, сразу после него, карту.

Карта Южной Америки: первая версия. Изображение от автора
world %>%  filter(continent == "Южная Америка") %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  scale_fill_continuous_sequential(palette= "Heat 2" )+  theme_void() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах жителей", 10)  )

Как видите, функция фильтрации dplyr работала хорошо; это и есть карта, которую мы хотели увидеть. Но правильно ли это?

Изменение климата – это огромная проблема, но уровень моря еще не поднялся настолько, чтобы затопить выдающуюся область, которая раньше находилась на севере Южной Америки. Что здесь произошло? Давайте теперь нарисуем другую карту с помощью координат и названиями полигонов.

Карта Южной Америки: вторая версия. Изображение автора
southamerica<-  world %>%  filter(continent=="Южная Америка") southamerica$lon<- sf::st_coordinates(sf::st_centroid(southamerica$geom))[,1]   southamerica$lat<- sf::st_coordinates(sf::st_centroid(southamerica$geom))[,2]southamerica %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  scale_fill_continuous_sequential(palette= "Heat 2" )+  theme_light() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах жителей", 10)  )+  geom_text_repel(aes(x=lon, y=lat, label= str_wrap(name_long,20)),                   color = "black",                   fontface = "bold",                   size = 2.8)

Вместо theme_void использовался theme_light, чтобы отображать координаты. Название полигонов потребовало больше работы. Нам пришлось вычислить центроид каждого полигона, а затем использовать эту информацию в качестве координат x и y в функции geom_text_repel.

С помощью этой новой версии карты и некоторых предыдущих знаний мы обнаружили, что пропавшей территорией была Французская Гвиана, между 0º и 10º северной широты и 53º и 55º западной долготы. Наша следующая задача – понять, как получить информацию о Французской Гвиане: полигон, население и некоторые координаты, чтобы заполнить нашу карту.

La Mer

Мне пришлось выделить Францию из остального мира, чтобы понять, как пакет {spData} обрабатывает данные карты этой страны. Вот результат.

Карта Франции. Изображение автора
france<-  world %>%  filter(iso_a2 == "FR")france %>%  ggplot() +  geom_sf(aes(fill=pop)) +  scale_fill_continuous_sequential(palette= "Heat 2", trans= "log2" )+  theme_light() +  theme(    #panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население", 30)  )

У Франции есть множество так называемых заморских территорий. Подход пакета {spData} заключался в представлении только основной территории, плюс Корсики, острова в Средиземном море, и Французской Гвианы, которая находится именно в диапазоне координат, характеризующем пробел на нашей последней карте Южной Америки.

Моя следующая попытка была добавить фрейм данных с геометрическими данными Франции к моему фильтру Южной Америки, но я знал, что мне понадобится больше информации. См. ниже

Южная Америка + Франция. Изображение автора
southamerica %>%  bind_rows(france) %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  scale_fill_continuous_sequential(palette= "Heat 2" )+  theme_light() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах человек", 10)  )+  geom_text_repel(aes(x=lon, y=lat, label= str_wrap(name_long,20)),                   color = "black",                   fontface = "bold",                   size = 2.8)

Как видно из кода, я использовал bind_row для объединения южноамериканских территорий с файлом формы Франции. Теперь у нас хорошо расположена Французская Гвиана. С другой стороны, на карте нет информации о населении, и Франция является частью Южной Америки с точки зрения истории колониализма.

Другими словами, я хотел такую карту.

Французская Гвиана на карте Южной Америки. Изображение автора
data_guiana<-  insee::get_idbank_list('TCRED-ESTIMATIONS-POPULATION') %>%  filter(str_detect(REF_AREA_label_fr,"Guyane")) %>%  filter(AGE == "00-") %>% #все возрасты  filter(SEXE == 0) %>% #мужчины и женщины  pull(idbank) %>%  insee::get_insee_idbank() %>%  filter(TIME_PERIOD == "2023") %>%   select(TITLE_EN,OBS_VALUE) %>%  mutate(iso_a2 = "FR")data_guiana <- janitor::clean_names(data_guiana)southamerica %>%  bind_rows(france) %>%  left_join(data_guiana) %>%  mutate(pop=ifelse(iso_a2=="FR",obs_value,pop))%>%  mutate(lon= ifelse(iso_a2=="FR", france[[11]][[1]][[1]][[1]][1,1], lon),         lat= ifelse(iso_a2=="FR",france[[11]][[1]][[1]][[1]][1,2], lat)) %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  scale_fill_continuous_sequential(palette= "Heat 2" )+  geom_text_repel(aes(x=lon, y=lat, label= str_wrap(name_long,20)),                   color = "black",                   fontface = "bold",                   size = 2.8)+  coord_sf(xlim = c(-82,-35), ylim=c(-60,15))+  theme_light() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах человек", 10)  )

Как вы можете прочитать, я использовал пакет R, произведенный официальным статистическим офисом Франции, чтобы получить население Гвианы. Кроме того, я ограничил карту соответствующими координатами, чтобы увидеть Южную Америку.

Emolduram e aquarelam o meu Brasil

Теперь, когда картограф наконец-то решил проблемы Южной Америки и сыграл на трубах мира с Францией, пришло время вернуться к данным и картам Бразилии. Помните, что я хочу сравнить некоторые детали переписи населения Бразилии с другими странами и территориями к югу от Панамы.

Данные переписи населения доступны в пакете R или по адресу API. Я выбрал более сложный вариант, используя API. Использование другого варианта в другой раз может быть хорошей идеей. Вот код и карта ниже, где я показываю население бразильских штатов в сравнении с другими южноамериканскими территориями.

Южная Америка + бразильские штаты. Изображение автора
central_america<-  world %>%  filter(subregion == "Центральная Америка")brasil<- geobr::read_country()estados<- geobr::read_state()#данные о населенииibge2022<-  get_municipalies_data()estados<-  estados %>%  inner_join(    ibge2022 %>%      rename(abbrev_state = uf) %>%      summarise(.by=abbrev_state,                pop = sum(populacao_residente)      )  )southamerica %>%  filter(iso_a2!="BR") %>%  bind_rows(france) %>%  left_join(data_guiana) %>%  mutate(pop=ifelse(iso_a2=="FR",obs_value,pop))%>%  mutate(lon= ifelse(iso_a2=="FR", france[[11]][[1]][[1]][[1]][1,1], lon),         lat= ifelse(iso_a2=="FR",france[[11]][[1]][[1]][[1]][1,2], lat)) %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  geom_sf(data=estados, aes(fill=pop/10^6)) +  geom_sf(data=brasil,fill=NA, color="#00A859", lwd=1.2)+  geom_sf(data= central_america,fill= "#808080")+  scale_fill_continuous_sequential(palette= "Heat 2" )+  geom_text_repel(aes(x=lon, y=lat,                       label= str_wrap(name_long,20)),                   color = "black",                   fontface = "bold",                   size = 2.8)+  coord_sf(xlim = c(-82,-35), ylim=c(-60,15))+  theme_void() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах", 10)  )

Я написал функцию get_municipalites_data, используя указанный выше API. Код доступен в моем gist. Обратите также внимание на две функции, которые предоставляют файлы формата shapefile, используемые для отображения границ Бразилии и ее подрегионов: read_country и read_states. Эти функции присутствуют в пакете {geobr}.

Я использовал еще один фильтр из датафрейма world. В этом случае целью является показ начала Центральной Америки и закраска ее карты серым цветом. Здесь мы столкнулись с культурным разногласием, так как мы узнали в Бразилии, что Америки имеют три подконтинента: Северная Америка, Центральная Америка и Южная Америка. Для авторов набора данных Центральная Америка является подрегионом Северной Америки. Теперь пришло время закончить свою работу. Я хочу показать названия восьми наиболее населенных территорий на карте. Даже в этом последнем рывке было несколько хитростей в коде.

Самые населенные территории. Изображение автора
estados$lon<- sf::st_coordinates(sf::st_centroid(estados$geom))[,1]   estados$lat<- sf::st_coordinates(sf::st_centroid(estados$geom))[,2]most_populated<-  southamerica %>%  filter(iso_a2 !="BR") %>%  rename(name= name_long) %>%  as_tibble() %>%  select(name, pop, lat, lon) %>%  bind_rows(    estados %>%      rename(name= name_state) %>%      as_tibble() %>%      select(name, pop, lat, lon)  ) %>%  slice_max(order_by = pop, n=8)southamerica %>%  filter(iso_a2!="BR") %>%  bind_rows(france) %>%  left_join(data_guiana) %>%  mutate(pop=ifelse(iso_a2=="FR",obs_value,pop))%>%  mutate(lon= ifelse(iso_a2=="FR", france[[11]][[1]][[1]][[1]][1,1], lon),         lat= ifelse(iso_a2=="FR",france[[11]][[1]][[1]][[1]][1,2], lat)) %>%  ggplot() +  geom_sf(aes(fill=pop/10^6)) +  geom_sf(data=estados, aes(fill=pop/10^6)) +  geom_sf(data=brasil,fill=NA, color="#00A859", lwd=1.2)+  geom_sf(data= central_america,fill= "#808080")+  scale_fill_continuous_sequential(palette= "Heat 2" )+  geom_text_repel(data= most_populated,                  aes(x=lon, y=lat,                       label= str_c(str_wrap(name,10),": ",round(pop/10^6,1))),                   color = "black",                   fontface = "bold",                   size = 2.9)+  coord_sf(xlim = c(-82,-35), ylim=c(-60,15))+  theme_void() +  theme(    panel.background = element_rect(fill="#0077be")  ) +  labs(    fill= str_wrap("Население в миллионах", 10)  )

Три бразильских штата входят в восемь наиболее населенных территорий в Южной Америке. Фактически, Сан-Паулу – второе по населению место на карте, превосходящее все страны, кроме Колумбии.

Теперь, сосредоточимся на коде. Вы можете видеть, что я создал новый фрейм данных для создания этого рейтинга, объединив два разных объекта sf. Я выбрал подмножество столбцов и изменил тип с sf на tibble, чтобы разрешить связывание строк.

Вот и все. Герой завершил один из возможных путей и оставил следы для следующего путешествия. Теперь ваша очередь. Вспомните все свои проекты, которые можно значительно улучшить с помощью картографического представления. Используя описанные выше инструкции и собирая все доступные данные о населении, социально-экономических проблемах и так далее, вам просто нужно выбрать переменную для заполнения полигонов.

Код и данные

Полный код доступен на gist.

Все бразильские наборы данных характеризуются как общественное достояние, поскольку они являются данными, произведенными федеральными учреждениями правительства и предоставленными в интернете в качестве активной прозрачности и подчиняются Бразильскому закону о доступе к информации.

IBGE: Бразильская перепись населения

IPEA: Бразильские shape-файлы

Французские данные доступны на портале открытых данных и указаны как открытая лицензия, которая позволяет использовать информацию в коммерческих целях.