В предыдущем сообщении я показал, как при помощи пакетов maptools и sp можно создать картограммы на основе свободно доступных шейп-фалов. Как это часто случается, в R имеется несколько способов достижения одной и той же цели. Не являются исключением и картограммы. Это сообщение будет посвящено построению картограмм средствами ggplot2 - пожалуй, самого популярного графического пакета для R. Следует сразу оговориться, что синтаксис команд ggplot2 является своего рода мини-языком программирования. Изложение основ ggplot2 не является целью данной статьи - для этого существуют соответствующие руководства, из которых особое внимание стоит обратить на официальную документацию пакета, а также на книги Wickham (2009) и Chang (2013). В приведенных ниже примерах я буду давать лишь краткие пояснения к коду, необходимые для его понимания. Кроме того, предполагается, что вы уже знакомы с содержанием предыдущего сообщения.
Загрузим шейп-файл, необходимый для построения карты Беларуси и отображения ее административно-территориальных единиц на уровне районов:
Как было отмечено ранее, объект Counties относится к объектам класса S4 и имеет сложную структуру. В то же время, единственный формат данных, который принимают функции пакета ggplot2, - это "таблица данных" (data frame). Соответственно, нам необходимо каким-то образом преобразовать объект Counties в таблицу данных. Сделать это позволяет функция fortify() из пакета ggplot2 (если этот пакет у вас еще не установлен, выполните команду install.packages("ggplot2")):
Теперь мы можем построить прототип нашей будущей картограммы при помощи следующей составной команды:
Рассмотрим отдельные части приведенной команды подробнее:
Теперь отобразим данные из столбца Value таблицы fake_data на картограмме:
Результатом приведенной выше команды будет картограмма с автоматически выбранной цветовой шкалой. Конечно, при желании мы можем изменить эту шкалу. Так, в рассматриваемом примере отображаемые на карте данные имеют среднее значение 0. Имеет смысл определенным образом выделить это значение на цветовой шкале, например, при помощи белого цвета. Для значений же, отклоняющихся от 0 в отрицательную и в положительную стороны, можно выбрать, например, оттенки синего и красного соответственно. Для создания подобных расходящихся (англ. diverging) цветовых шкал в пакете ggplot2 служит функция scale_fill_gradient2(), которая работает примерно следующим образом (обратите также внимание на аргумент colour = "gray" функции geom_map() - он добавлен для обводки границ районов серым цветом):
При необходимости мы можем выполнить тонкую настройку и других деталей внешнего вида графика. В частности, при помощи функции theme() ("тема", или "шаблон") можно отключить отображение серого фона, координатной сетки, а также осей и их подписей:
counties <- fortify(Counties, region = "NAME_2")
# при помощи аргумента region = "NAME_2" мы указываем
# переменную (NAME_2) в которой хранятся идентификаторы
# административных единиц - районов str(counties) 'data.frame': 42659 obs. of 7 variables: $ long : num 29.1 29.1 29.1 29.1 29.1 ... $ lat : num 52.9 52.9 52.9 52.9 52.8 ... $ order: int 1 2 3 4 5 6 7 8 9 10 ... $ hole : logi FALSE FALSE FALSE FALSE FALSE FALSE ... $ piece: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ... $ group: Factor w/ 118 levels "Aktsyabar.1",..: 1 1 1 1 1 1 1 1 1 1 ... $ id : chr "Aktsyabar" "Aktsyabar" "Aktsyabar" "Aktsyabar" ...
Теперь мы можем построить прототип нашей будущей картограммы при помощи следующей составной команды:
Рассмотрим отдельные части приведенной команды подробнее:
- ggplot(): создание статистических графиков средствами ggplot2 напоминает послойное создание изображений в программе Adobe Photoshop. При помощи функции ggplot() мы инициируем пустой слой графика, поверх которого далее будут добавляться другие слои, содержащие определенные графические элементы (в частности, изображение карты).
- geom_map(): создает слой с картой, внешний вид которой задается при помощи соответствующих аргументов. Так, при помощи аргумента data мы указываем таблицу данных, в которой содержатся подлежащие отображению на карте данные. Поскольку на данном этапе никаких таких данных у нас нет, в качестве "заглушки" мы просто укажем таблицу counties. Аргумент aes() позволяет настроить "эстетические параметры" (англ. aesthetics) создаваемого слоя, и в частности - указать, какая переменная в таблице с данными содержит идентификаторы административно-территориальных единиц (районов). Аргумент map служит для указания таблицы, содержащей координаты соответствующих полигонов на карте (в нашем случае это counties - таблица, которую мы создали при помощи функции fortify() из объекта Counties).
- expand_limits(): в отличие от других функций ggplot2, которые предназначены для создания новых слоев с графическими элементами, функция geom_map() "не умеет" самостоятельно определять оптимальные пределы значений x- и y-координат. Сделать это ей помогает функция expand_limits().
- coord_map(): задает тип картографической проекции. В приведенном примере использован тип "polyconic" - поликоническая проекция. Доступны также многие другие типы, реализованные в пакете mapproj (подробнее см. справочный файл, доступный по команде ?mapproject).
fake_data <- as.data.frame(Counties@data) fake_data$Value <- rnorm(nrow(fake_data))
Теперь отобразим данные из столбца Value таблицы fake_data на картограмме:
library(scales) # для функции muted (см. ниже)
ggplot() + geom_map(data = fake_data, aes(map_id = NAME_2, fill = Value), colour = "gray", map = counties) + expand_limits(x = counties$long, y = counties$lat) + scale_fill_gradient2(low = muted("blue"), midpoint = 0, mid = "white", high = muted("red"), limits = c(min(fake_data$Value), max(fake_data$Value))) + coord_map("polyconic")
ggplot() + geom_map(data = fake_data, aes(map_id = NAME_2, fill = Value), colour = "gray", map = counties) + expand_limits(x = counties$long, y = counties$lat) + scale_fill_gradient2(low = muted("blue"), midpoint = 0, mid = "white", high = muted("red"), limits = c(min(fake_data$Value), max(fake_data$Value))) + coord_map("polyconic") + theme( axis.line = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), plot.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank() )
Отправить комментарий