Kuvan labelointi data.frame:lla R:n ggplot2:ssa

Luokat: data

Tehdäänpä tiivis tekninen bloggaus lähinnä vinkkinä itselleni tulevaisuuteen. Eli kun seuraavan kerran googlaan lauseella ggplot label with dataframe data.frame niin löydän tänne.

ggplot2 on suosittu R-kielen paketti staattisen grafiikan tekemiseen. Paketin funktiot geom_label ja geom_text (kuin myös geom_sf_text, geom_sf_label ja ggrepel-paketin geom_text_repel ja geom_label_repel) ovat näppäriä tekstin lisäämiseen kuviin. Tavanomainen käyttötarkoitus on esim. nimetä viivakuvion viiva suoraan kuvaan, laittaa tolpan nokkaan sarjan arvo tai karttaan pitäjän nimi ja väkiluku.

Menneellä viikolla minulle tuli tarve saada karttaan jokaisen alueen kohdalle pieni taulukko, jossa kolme saraketta ja kolme riviä. Yleensä käytän tällaisiin leaflet-pakettia ja teen vuorovaikutteisen kartan Eduskuntavaalit 2019: Helsingin äänestysalueiden top 3. Saavutettavuuden aikakaudella olen palannut staattisiin karttoihin, joille on helppo antaa alt-teksti ja tein saman sitten ggplot2:lla. Tässä on esimerkkikoodi, jossa haetaan kuntatason data se aggregoidaan vaalipiiritasolle. Vaalipiireittäin haluan sitten näyttää vaalipiirin nimen, kuntien määrän ja vaalipiirin pinta-alan.

library(dplyr)
library(glue)
library(ggplot2)
library(tidyr)
library(readr)
library(geofi)
library(sf)

muni <- get_municipalities()
vaalipiiri <- muni %>% 
  group_by(vaalipiiri_name_fi) %>% 
  summarise(n_muni = n())
vaalipiiri$area <- as.integer(round(sf::st_area(vaalipiiri)/1000000))

print(vaalipiiri)
## Simple feature collection with 13 features and 3 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: 83747.59 ymin: 6637032 xmax: 732907.7 ymax: 7776431
## Projected CRS: ETRS89 / TM35FIN(E,N)
## # A tibble: 13 × 4
##    vaalipiiri_name_fi               n_muni                            geom  area
##  * <chr>                             <int>                  <GEOMETRY [m]> <int>
##  1 Ahvenanmaan maakunnan vaalipiiri     16 MULTIPOLYGON (((113645.7 66811…  1525
##  2 Hämeen vaalipiiri                    21 POLYGON ((399519.5 6739515, 39… 12682
##  3 Helsingin vaalipiiri                  1 MULTIPOLYGON (((402737.7 66807…   264
##  4 Kaakkois-Suomen vaalipiiri           27 MULTIPOLYGON (((508037.2 66841… 28966
##  5 Keski-Suomen vaalipiiri              22 POLYGON ((416178.3 6847939, 41… 18926
##  6 Lapin vaalipiiri                     21 POLYGON ((388163.1 7285002, 38… 98930
##  7 Oulun vaalipiiri                     38 MULTIPOLYGON (((382095.7 70603… 61918
##  8 Pirkanmaan vaalipiiri                23 POLYGON ((329878.3 6763699, 32… 15513
##  9 Satakunnan vaalipiiri                16 MULTIPOLYGON (((237353.5 67582…  8354
## 10 Savo-Karjalan vaalipiiri             32 POLYGON ((549385.7 6881072, 54… 43900
## 11 Uudenmaan vaalipiiri                 25 MULTIPOLYGON (((300620.8 66443…  9335
## 12 Vaasan vaalipiiri                    40 MULTIPOLYGON (((225346.6 68870… 27208
## 13 Varsinais-Suomen vaalipiiri          27 MULTIPOLYGON (((194643.4 66445… 10444

Seuraavaksi tarvitsemme kullekin vaalipiirille sen oman pienen datan. Tavoitteena siis tämän tyyppinen label:

Vaasan vaalipiiri

vpiiri  Vaasan
n_muni      40
area     27208
pad_same_length_plus_2 <- function(x,
                                   padchar=" ",
                                   padside= "right", 
                                   padplus = 2){
  stringr::str_pad(x, max(nchar(x))+padplus, side=padside, pad=padchar)
                                   } 
vaalipiiri_df <- st_drop_geometry(vaalipiiri) %>% 
  setNames(c("vpiiri","n_muni","area"))

vpt <- unique(vaalipiiri_df$vpiiri)
vplista <- list()
for (i in seq_along(vpt)){
  tmpdat <- tibble(vaalipiiri = vpt[i],
                   label = vaalipiiri_df %>%
                     filter(vpiiri == vpt[i]) %>%
                     mutate_all(as.character) %>%
                     mutate(vpiiri = gsub(" vaalipiiri| maakunnan", "", vpiiri)) %>% 
                     pivot_longer(1:3) %>% 
                     mutate(name = pad_same_length_plus_2(name, padplus = 0),
                            value = pad_same_length_plus_2(value, padside = "left", padplus = 0))  %>%
                     setNames(c(" "," ")) %>% 
                     format_tsv() %>%  
                     sub("\n$", "", .)) %>%
    mutate(label = paste0(vaalipiiri,"\n",label))
  vplista[[vpt[i]]] <-  tmpdat
}
label_data <- do.call(bind_rows, vplista)
mapdata2 <- left_join(vaalipiiri,label_data, by = c("vaalipiiri_name_fi" = "vaalipiiri"))
ggplot(mapdata2, aes(fill = area,
                    label = label)) +
  labs(title = "Vaalipiirit vertailussa",
       fill = "Vaalipiirin pinta-ala") +
  geom_sf() +
  ggrepel::geom_label_repel(data = mapdata2 %>%
                             sf::st_set_geometry(NULL) %>%
                             bind_cols(mapdata2 %>% 
                                         sf::st_centroid() %>% 
                                         sf::st_coordinates() %>% as_tibble()),
                           aes(label = label,
                               x = X,
                               y = Y#,
                               ),
                           fill = alpha("white", 2/3),
                           color = "black",
                           family = "Space Mono",
                           size = 3.5,
                           max.overlaps = 35) +
  scale_fill_viridis_c()

Käännökset

Katso myös

',