2 мая 2011 г.

Рисование карт в R

При подготовке к выступлению на конференцию оказалось, что мне нужна карта. Не очень сложная — показать 14 областей Украины, отметить их цветом. Если бы такая задача стояла в школе, я бы взял контурную карту и аккуратно разрисовал бы её. Но ведь у меня есть под рукой компьютер! Да и таких задач может быть много. Поэтому родилось желание найти способ(ы) рисовать такую красоту на машине.

Вариантов решения может быть несколько.

Первый, тупой — нарисовать от руки, отсканировать и наслаждаться.

Второй, ещё тупее — скачать готовую карту и долго вычищать её средствами фотошопа, гимпа, пайнтбраша и прочими графическими редакторами.

Третий — воспользоваться специальным ПО (ведь кто-то ж эти карты делает!). Надо сказать, что это требует некоторого терпения и желания разобраться как в специальной терминологии, так и в самой, собственно, начинке этого ПО.

Попробуем сделать это с помощью R, в котором даже есть специальный пакет maps, который в связке с ggplot2, говорят, способен творить чудеса. Чуда однако не получилось по простой причине: более-менее актуальные данные в нём есть только для США. Для всего же остального мира — на уровне макрорегионов.

Тем не менее, выход есть (и, наверняка, не один) — проект Global Administrative Areas (http://gadm.org/) не только содержит информацию об актуальном расположении границ административных территорий самого разного уровня, но и предоставляет её в понятном для R виде (http://blog.revolutionanalytics.com/2009/10/geographic-maps-in-r.html).

Пожалуй, это именно то, что мне нужно. Пример работы, указанный на сайте проекта, демонстрирует процесс визуализации языкового разнообразия Швейцарии.

Попытаемся по аналогии реализовать нашу задачу: выделить те области Украины, где в 2009–2010 гг. проводились биоповеденческие исследования МСМ.

В терминале R устанавливаем и загружаем нужный нам пакет sp:

install.packages(sp)
library(sp)


Далее следует найти данные для Украины. Идём на http://gadm.org/country и в выпадающем списке стран выбираем Ukraine, а в списке нужных форматов файлов — R Data. После нажатия OK открывается страничка загрузки, где есть две ссылки.

Первая (Division Level 1, http://gadm.org/data/rda/UKR_adm1.RData) позволяет загрузить файл, в котором территория Украины разделена по административно-территориальным единицам наивысшего уровня — области, АР Крым, г. Киев и г. Севастополь.

Вторая (Division Level 2, http://gadm.org/data/rda/UKR_adm2.RData) предоставляет значительно более подробные сведения — города, районы (для крупных городов и районы города), территории соответствующих горсоветов.

В терминале R загружаем нужный нам файл:

ukr = url("http://gadm.org/data/rda/UKR_adm1.RData")
print(load(ukr))
close(ukr)
str(gadm, max.level=2)


Примечание: после команды print(load(ukr)) R выдаёт сообщение, что массив ukr преобразован в массив gadm.

Если теперь попытаться посмотреть на карту:

spplot(gadm)

то получим следующую схему:



Она показывает, какие типы карт доступны. Например, карта распределения территорий по их площади (Shape_Area) — чем меньше площадь соответствующей единицы, тем горячее её цвет:

spplot(gadm, "Shape_Area")



Если теперь посмотреть на сам массив gadm (привожу только самое начало), то окажется, что имена карт являются заголовками соответствующих столбцов, а строки соответствуют свойствам административно-территориальных единиц (название, тип, площадь, протяжённость границ и т. п.):

> gadm
An object of class "SpatialPolygonsDataFrame"
Slot "data":
ID_0 ISO NAME_0 ID_1 NAME_1
0 231 UKR Ukraine 3136 Cherkasy
1 231 UKR Ukraine 3137 Chernihiv
2 231 UKR Ukraine 3138 Chernivtsi
3 231 UKR Ukraine 3139 Crimea
4 231 UKR Ukraine 3140 Dnipropetrovs'k


Наша задача — создать новый столбец с нужными нам свойствами перечисленных единиц. Пускай он называется monitoring и содержит три уровня "не было", "был один мониторинг в 2009 г.", "было два мониторинга в 2009 и 2010 гг.":

monitoring = c("Було в 2009 р.","Не було","Не було","Було в 2009 р.","Було в 2009 р.","Було в 2009 та 2010 рр.","Було в 2009 р.","Було в 2009 р.","Було в 2009 р.","Не було","Не було","Було в 2009 р.","Не було","Було в 2009 р.","Було в 2009 р.","Було в 2009 та 2010 рр.","Було в 2009 р.","Було в 2009 р.","Не було","Не було","Не було","Не було","Було в 2009 р.","Не було","Не було","Не було","Не було")
gadm$monitoring = as.factor(monitoring)
color = rainbow(length(levels(gadm$monitoring)))


Наконец, всё готово и можно полюбоваться результатом:

spplot(gadm,"monitoring",col.regions=color)



Задача решена. На этом можно было бы и закончить. Но хочу напоследок отметить: то, что сейчас предстало как нечто само собой разумеющееся, потребовало полдня усилий, чтобы понять как это работает. При этом усилия прилагал мой БФ. Я лишь описал его действия.
Автор:

3 комментария:

М. Касянчук комментирует...

Инструмент для рисования карт в OpenOffice: http://gis-lab.info/qa/geooo.html

Хоть им и легче управлять, но он в отличие от R не даёт кода, который можно вставить в LaTeX.

Асджадс комментирует...

Браво! Статья достойная! И с виду так не сложно сделать фоновую картограмму. И код прописали и описание, спасибо :). Однозначно в Delicious под тегами visualization, cartogram, r.

М. Касянчук комментирует...

Спасибо, Лёша :) Вы очень добры :)