Улучшить центрирование названий округов ggplot & maps - PullRequest
14 голосов
/ 25 февраля 2012

Ранее я опубликовал вопрос о том, как нанести на карту названия округов с помощью ggplot и найденных карт ЗДЕСЬ .Мой первый подход состоял в том, чтобы взять все координаты широты и долготы для каждой страны, как показано здесь: enter image description here

К счастью, у Андри было 2 предложения по улучшению центрирования с использованием центра диапазонов, а затемordin_map (){который, кажется, сохраняет правильное соотношение сторон}.Это значительно улучшило центрирование, как показано здесь: enter image description here

Я думаю, что это выглядит лучше, но все еще есть некоторые проблемы с проблемами перекрытия.Я надеюсь на дальнейшее улучшение центрирования (в той же теме Джастин предложил подход kmeans).Я согласен с поворотом текста, если это необходимо, но я надеюсь, что имена, которые центрированы и повернуты при необходимости (они выходят за границы округа), позволяют лучше отображать названия округов на карте.

Есть идеи?

library(ggplot2); library(maps)

county_df <- map_data('county')  #mappings of counties by state
ny <- subset(county_df, region=="new york")   #subset just for NYS
ny$county <- ny$subregion
p <- ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA)

#my first approach to centering
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, FUN=mean)
ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=3)

#Andrie's much improved approach to centering
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                    FUN=function(x)mean(range(x)))
ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=3) +
    coord_map()

Ответы [ 5 ]

8 голосов
/ 26 февраля 2012

Поскольку я работал над этим вчера вечером в Talk Stats ( ссылка ), на самом деле довольно просто (как результат часов, которые я провел ранним утром!), Если вы используете пространственный пакет R ( зр ). Я протестировал некоторые из их других функций, чтобы создать объект SpatialPolygons , для которого можно использовать координаты для возврата центроида многоугольника. Я сделал это только для одного графства, но точка метки объекта Polygon (S4) соответствовала центроиду. Если предположить, что это правда, то точки меток объектов Polygon являются центроидами. Я использую этот небольшой процесс, чтобы создать фрейм данных центроидов и использовать их для построения карты.

library(ggplot2)  # For map_data. It's just a wrapper; should just use maps.
library(sp)
library(maps)
getLabelPoint <- # Returns a county-named list of label points
function(county) {Polygon(county[c('long', 'lat')])@labpt}

df <- map_data('county', 'new york')                 # NY region county data
centroids <- by(df, df$subregion, getLabelPoint)     # Returns list
centroids <- do.call("rbind.data.frame", centroids)  # Convert to Data Frame
names(centroids) <- c('long', 'lat')                 # Appropriate Header

map('county', 'new york')
text(centroids$long, centroids$lat, rownames(centroids), offset=0, cex=0.4)

Это не будет работать хорошо для каждого многоугольника. Очень часто процесс маркировки и аннотации в ГИС требует настройки меток и аннотации для тех особых случаев, которые не соответствуют автоматическому (систематическому) подходу, который вы хотите использовать. Подход «код-взгляд-код», к которому мы привыкли, не годится. Лучше включить проверку того, что метка заданного размера для данного графика будет вписываться в многоугольник; если нет, удалите его из записи текстовых меток и вставьте вручную позже, чтобы соответствовать ситуации - например, добавьте линию выноски и аннотируйте в сторону многоугольника или поверните метку в сторону, как это было показано в другом месте.

2 голосов
/ 26 февраля 2019

Это было очень полезное обсуждение.В интересах тех, кто вырос с dplyr, здесь есть небольшой твик, использующий трубы вместо aggregate:

library(maps); library(dplyr); library(ggplot2)
ny <- map_data('county', 'new york') 

cnames1 <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                     FUN=function(x)mean(range(x)))
cnames2 <- ny %>% group_by(subregion) %>%
    summarize_at(vars(long, lat), ~ mean(range(.)))

all.equal(cnames1, as.data.frame(cnames2))
1 голос
/ 26 февраля 2012

Я думаю, что самый простой ответ на этот вопрос - Андри уже решила большую часть ручной работы. Остальное должно быть завершено с некоторыми хорошими настройками и методами. Когда вы смотрите на сюжет после предложения Андри, большинство всего приличного, за исключением некоторых надоедливых размещений, которые можно улучшить с помощью изменения широты / долготы или поворота. У меня есть пример для суфолька (внизу справа) и геркимера (в центре), поскольку положение суфолька можно улучшить с помощью настройки широты / долготы и геркимера с помощью вращения.

До: Before

cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                    FUN=function(x)mean(range(x))) #Andrie's code

cnames[52, 2:3] <- c(-73, 40.855)  #adjust the long and lat of poorly centered names
cnames$angle <- rep(0, nrow(cnames)) #create an angle column
cnames[22, 4] <- -90    #adjust the angle of atypically shaped

ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion, colour=col, 
    angle=angle), size=3) + coord_map()

Это дает нам: enter image description here

Если у кого-то нет лучшего способа, я отмечу этот ответ как правильный.

0 голосов
/ 11 февраля 2013

Существует библиотека маркировки PAL , которая, кажется, выполняет именно то, что вы ищете, автоматически. Этот скриншот взят с их сайта:

PAL website screenshot

Я не нашел для этого R-интерфейса. Краткое руководство по для выполнения вашей собственной интеграции PAL в вашем любимом ГИС-приложении предполагает, что сама интеграция должна быть выполнимой. Однако в контексте ggplot2 это означает, что размещение меток должно выполняться во время рендеринга - я понятия не имею, возможно ли это или что нужно сделать для достижения этого.

0 голосов
/ 25 февраля 2012

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

...