Plusieurs points à considérer.
1 - lieu optimal à des fins d'annotation dans un polygone
Dans un monde idéal, chaque polygone est similaire à un cercle et son centre est le meilleur endroit pour placer une étiquette de texte (par exemple Texas). En réalité, les régions de carte sont de toutes sortes de formes, & peut même ne pas être en une seule pièce (par exemple Michigan). Le point mathématique moyen/médian peut être sur le bord ou à l'extérieur du polygone (par exemple en Floride). R ne va pas être si bon pour essayer de comprendre ces complications. J'utiliserais un logiciel SIG à la place.
Cependant, si votre cas d'utilisation est des États-Unis, l'ensemble de données state.vbm.center
vient déjà avec un très bon jeu de coordonnées par défaut. Ses états de fichier d'aide:
state.vbm.center sont les coordonnées des centres d'état pour l'annotation fins.
Jetons un coup d'oeil à où ces points sont les suivants:
#data
mapbase <- map_data("state.vbm")
data(state.vbm.center)
cnames <- state.vbm.center %>% as.data.frame() %>%
mutate(region = unique(mapbase$region))
#actual plotting
ggplot()+
geom_polygon(data=mapbase,
aes(long, lat, group = region, fill = region),
alpha = 0.3) +
coord_fixed() + theme_void() +
geom_point(data = cnames,
aes(x, y)) +
scale_fill_discrete(guide = F)
Ce n'est pas trop mal. Si tout ce que vous devez étiqueter sont des noms d'état, cela devrait suffire:
cnames$abb <- state.abb
ggplot()+
geom_polygon(data=mapbase,
aes(long, lat, group = region, fill = region),
alpha = 0.3) +
coord_fixed() + theme_void() +
geom_text(data=cnames,
aes(x, y , label = abb),
color= "black", size=3, fontface = 2,
hjust = 0.5, vjust = 0.5) + #central alignment
scale_fill_discrete(guide = F)
2 - étiquettes longues Montage dans des espaces restreints
Il est très bien ajusté des étiquettes courtes dans les polygones de carte, mais si vous voulez inclure plus d'informations (nom complet de chaque état, taux de natalité, taux de criminalité, taux de chômage, niveau d'éducation, fourchette de revenu, densité de population, proportion de personnes ayant voté aux dernières élections, ...), vais commencer à manquer d'espace dans le plus petit/plus wei polygones formés en forme de.
Une approche double peut être adoptée à ce stade, en gardant l'information dans les plus grands polygones, & en plaçant les plus petits polygones séparément d'un côté comme une légende partielle. Pour les États américains, la zone d'état fait partie du paquet datasets
standard, ce qui nous permet d'économiser la peine de le calculer:
# incorporate area information & identify small area states
cnames$area <- state.area
ggplot(cnames %>%
mutate(region = factor(region, levels = region[order(area)])),
aes(x = region, y = area)) + geom_col() +
theme_classic() +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
# the first 7 states (up to Maryland) are noticeably smaller than the rest
Choisissez des belle zone vide sur votre carte pour les petits États. Je décidé de les aligner verticalement dans une colonne de longitude = 140, & latitude allant de 0 à 60:
library(tidyr)
legend.states <- cnames$region[which(cnames$area <= 10577)]
legend.states <- as.data.frame(legend.states)
legend.states$long1 <- 140
legend.states$lat1 <- seq(0, 60, length.out = nrow(legend.states))
legend.states <- legend.states %>%
mutate(long2 = long1 + 5, lat2 = lat1) %>%
mutate(long3 = long2, lat3 = lat2 - 5) %>%
mutate(long4 = long1, lat4 = lat3) %>%
mutate(long5 = long1, lat5 = lat1) %>%
gather(k, v, -legend.states) %>%
mutate(order = as.integer(substring(k, nchar(k))),
k = gsub("[0-9]", "", k)) %>%
spread(k, v) %>%
rename(region = legend.states) %>%
mutate(group = mapbase$group[match(region, mapbase$region)]) %>%
select(long, lat, group, order, region) %>%
mutate(subregion = NA)
# add legend polygons to the original polygon dataset
mapbase2 <- rbind(mapbase, legend.states)
Changer l'annotation coordonnées pour ces petits états, de telle sorte qu'ils sont alignés sur les positions de la boîte de légende:
cnames2 <- left_join(cnames,
legend.states %>% filter(order %in% c(1, 4)) %>%
group_by(region) %>%
summarise(long = mean(long) + 7,
lat = mean(lat))) %>%
mutate(x = coalesce(long, x),
y = coalesce(lat, y),
hjust = ifelse(is.na(lat), 0.5, 0))
# left alignment (hjust=0) for small state text, central alignment (hjust=0.5) otherwise.
tout Assemblez:
ggplot()+
geom_polygon(data=mapbase2,
aes(long, lat, group = region, fill = region),
alpha = 0.3) +
coord_fixed() + theme_void() +
geom_text(data=cnames2,
aes(x, y , label = abb, hjust = hjust),
size=3, fontface = 2,
vjust = 0.5) +
scale_fill_discrete(guide = F)
(Remarque: pour un texte plus long, vous devrez probablement également augmenter les limites de l'axe des x et/ou insérer des sauts de ligne.)