Başlangıç

Bir haftasonu projesi olarak ortaya çıkan ggplot paketi ile türkiye haritası üzerinde görselleştirme yapmayı anlatacağım. İnternetteki birçok harita görselleştirmesi örnekleri genellikle Amerika üzerine. Ben de Türkiye haritasını nasıl oluşturabilirim diye araştırmaya başladım. Her ne kadar coğrafya ve coğrafik veriye dair bilgim olmasa da, biraz incelemeyle yol katettim.

Bu yolda aşağıdaki aşamaları izleyeceğiz:

İndirme

Öncelikle buradaki http://www.gadm.org/country linkten Türkiye’yi seçip, dosya formatı olarak da R (SpatialPolygonsDataFrame)’i seçiyoruz. Not olarak buradan indireceğiniz veriyi ticari amaçla kullanamazsınız.

İndirme kısmında level 0, level 1 ve level 2 göreceksiniz. Bunların anlamı yukarıda haritadaki çizgilerdir aslında. level 0 il ve ilçelerin olmadığı sadece türkiye’nin şeklini oluştur. level 1 kırmızı çizgileri yani şehirleri temsil eder. level 2 de ilçeleri de gösterir. level 2 yi indirdiğimizde aslında level 1 ve level 0’ında verisine sahip olmuş oluyoruz ancak ihtiyacımız olmadığından level 1’i indiriyoruz.

Veriyi R’ye Aktarmak

Veriyi aktarmadan önce bazı paketleri çağırıyoruz.

library(tidyverse) 
## Loading tidyverse: ggplot2
## Loading tidyverse: tibble
## Loading tidyverse: tidyr
## Loading tidyverse: readr
## Loading tidyverse: purrr
## Loading tidyverse: dplyr
## Conflicts with tidy packages ----------------------------------------------
## filter(): dplyr, stats
## lag():    dplyr, stats
library(sp) # Konumsal (Spatial) veri için

SpatialPolygonsDataFrame veriyi aktarmak için;

TUR <- readRDS("TUR_adm1.rds")

Hızlıca plot fonksiyonuyla haritamıza bakabiliriz ancak biz görselleşmeyi ggplot ile yapacağız.

plot(TUR)

SpatialPolygonsDataFrame

Bu veri türü içinde metadata ve her ilin sınır kordinatlarının olduğu matrixler içeriyor.

Bizim uğraşacağımız kısım aslında SpatialPolygonsDataFrame içinde data kısmı ona da, TUR@data şeklinde ulaşabiliyoruz.

TUR@data %>% as_tibble() %>% head(10)
## # A tibble: 10 x 13
##    OBJECTID  ID_0   ISO NAME_0  ID_1    NAME_1 HASC_1 CCN_1 CCA_1 TYPE_1
##       <int> <int> <chr>  <chr> <int>     <chr>  <chr> <int> <chr>  <chr>
##  1        1   235   TUR Turkey     1 Çanakkale  TR.CK    NA           Il
##  2        2   235   TUR Turkey     2   Çankiri  TR.CI    NA           Il
##  3        3   235   TUR Turkey     3     Çorum  TR.CM    NA           Il
##  4        4   235   TUR Turkey     4     Adana  TR.AA    NA           Il
##  5        5   235   TUR Turkey     5  Adiyaman  TR.AD    NA           Il
##  6        6   235   TUR Turkey     6     Afyon  TR.AF    NA           Il
##  7        7   235   TUR Turkey     7      Agri  TR.AG    NA           Il
##  8        8   235   TUR Turkey     8   Aksaray  TR.AK    NA           Il
##  9        9   235   TUR Turkey     9    Amasya  TR.AM    NA           Il
## 10       10   235   TUR Turkey    10    Ankara  TR.AN    NA           Il
## # ... with 3 more variables: ENGTYPE_1 <chr>, NL_NAME_1 <chr>,
## #   VARNAME_1 <chr>

ID_0: Ülke kimlik numarası diyebiliriz.
ID_1: Şehirlerin kimlik numaraları, bu numaraları plaka kodları ile karıştırmayın.
ID_2: Bu veride yok ancak ilçelerin kimlik numaraları
Aynı şekilde,
NAME_0: Ülke ismi
NAME_1: Şehir isimleri
NAME_2: İlçe İsimleri

ggplot(TUR, aes(x = long, y = lat)) +
  geom_polygon()
## Regions defined for each Polygons

Grafiğin böyle olmasının sebebi ggplot’un verinin ne verisi olduğunu bilmemesinden, biraz düzeltelim.

ggplot(TUR, aes(x = long, y = lat)) +
  geom_polygon(aes(group = group)) +
  coord_fixed()
## Regions defined for each Polygons

Şehirleri ayırmak için de fortify fonksiyonunu kullanacağız.

TUR_for <- fortify(TUR) # Bu fonksiyon 'sp' paketinin içinde.
## Regions defined for each Polygons
head(TUR_for)
##       long      lat order  hole piece id group
## 1 27.28653 40.47514     1 FALSE     1  1   1.1
## 2 27.28653 40.47486     2 FALSE     1  1   1.1
## 3 27.28681 40.47486     3 FALSE     1  1   1.1
## 4 27.28681 40.47458     4 FALSE     1  1   1.1
## 5 27.28708 40.47458     5 FALSE     1  1   1.1
## 6 27.28708 40.47181     6 FALSE     1  1   1.1

Aslında, SpatialPolygonsDataFrame türünü dataframe’e çevirdi diyebiliriz. şehirlerin kordinatlarını order’a göre yerleştiriyor. id yukarıda bahsettiğim şehrin kimlik numarası.

ggplot(TUR_for) + 
  geom_polygon(aes(x = long, y = lat,
                   group = group),
                   color = "white",
                   fill = "#97ECEA") +
  theme_void() + 
  coord_fixed()

TÜİK Verisi

TÜİK’ten aldığım veriyi aktarmadan önce bahsetmeliyim ki, yukarıda gösterdiğimiz coğrafik verinin ve tüik verisinin doğru birleştirme yapmak için şehir isimlerinin birbiriyle uyuşması gerekiyor. Bu sebeple ben iki veride de bazı düzenlemeler yaptım. Şehir isimlerindeki Türkçe karakterleri İngilizceye çevirdim. Diğer bazı küçük düzenlemeleri aşağıda paylaştığım github linkimdeki map.R dosyasında bulabilirsiniz.

Daha hızlı ilerleyebilmek için map.R dosyasını aktarıyorum.

source("map.R")

Üzerinde çalışacağım veri, ülke içindeki şehirlerin göç alma sayıları. TÜİK’ten aldığım veri 2014-2016 yılına ait ancak ben 2016 ait bir görselleştirme yapacağım.

mig <- read_csv("migration/clean_migration.csv")
## Parsed with column specification:
## cols(
##   yil = col_integer(),
##   aldigi_sehir = col_character(),
##   sehir = col_character(),
##   sayi = col_integer()
## )
mig %>% head()
## # A tibble: 6 x 4
##     yil aldigi_sehir          sehir  sayi
##   <int>        <chr>          <chr> <int>
## 1  2014        Adana       Adıyaman   752
## 2  2014        Adana Afyonkarahisar   294
## 3  2014        Adana           Ağrı   276
## 4  2014        Adana        Aksaray   500
## 5  2014        Adana         Amasya   120
## 6  2014        Adana         Ankara  3656

Öncelikle verideki şehir isimlerindeki türkçe karakterleri ingilizce karakterlere çevirelim.

mig$aldigi_sehir <- tr_to_en(mig$aldigi_sehir) 
mig$sehir <- tr_to_en(mig$sehir)

İstanbul’un 2016’yılında aldığı göçü gösterelim. Bunun için de veriyi özelleştirelim.

mig_ist_2016 <- mig %>%
  filter(yil == 2016, sehir == "Istanbul") %>%
  select(-c(yil,sehir))

mig_ist_2016 %>% head()
## # A tibble: 6 x 2
##     aldigi_sehir  sayi
##            <chr> <int>
## 1          Adana  6933
## 2       Adiyaman  4033
## 3 Afyonkarahisar  1863
## 4           Agri  6709
## 5        Aksaray  1314
## 6         Amasya  2460

TUR verisindeki ID_1 kimlik numaralarını TÜİK verisine dahil etmemiz gerekiyor. Bu sebeple, left_join ile NAME_1 ve aldigi_sehire göre birleştiriyoruz.

id_and_cities_ist <- data_frame(id = rownames(TUR@data),
                            aldigi_sehir = TUR@data$NAME_1) %>% 
  left_join(mig_ist_2016, by = "aldigi_sehir")

id_and_cities_ist %>% head()
## # A tibble: 6 x 3
##      id   aldigi_sehir  sayi
##   <chr>          <chr> <int>
## 1     1      Canakkale  4563
## 2     2        Cankiri  2868
## 3     3          Corum  2419
## 4     4          Adana  6933
## 5     5       Adiyaman  4033
## 6     6 Afyonkarahisar  1863

Son haritayı oluşturmak için yukarıdaki oluşturduğumuz TUR_for ile id_and_cities_ist verisini birleştiriyoruz.

final_ist_map <- left_join(TUR_for, id_and_cities_ist, by = "id")

final_ist_map %>% head()
##       long      lat order  hole piece id group aldigi_sehir sayi
## 1 27.28653 40.47514     1 FALSE     1  1   1.1    Canakkale 4563
## 2 27.28653 40.47486     2 FALSE     1  1   1.1    Canakkale 4563
## 3 27.28681 40.47486     3 FALSE     1  1   1.1    Canakkale 4563
## 4 27.28681 40.47458     4 FALSE     1  1   1.1    Canakkale 4563
## 5 27.28708 40.47458     5 FALSE     1  1   1.1    Canakkale 4563
## 6 27.28708 40.47181     6 FALSE     1  1   1.1    Canakkale 4563

Haritayı oluşturmadan hemen önce 2016 yılında kaç kişi istanbul’a gelmiş diye bakalım.

sum(mig_ist_2016$sayi)
## [1] 369582

Haritamız:

ggplot(final_ist_map) +
  geom_polygon( aes(x = long, y = lat, group = group, fill = sayi),
                color = "grey") +
  coord_map() +
  theme_void() + 
  labs(title = "2016 Yılındaki İstanbul'un Aldığı Göç Sayısı",
       subtitle = paste0("Toplam Sayı: ", sum(mig_ist_2016$sayi)),
       caption = "Kaynak: Türkiye İstatistik Kurumu") +
  scale_fill_distiller(name = "Göç Sayısı",
                       palette = "Spectral", limits = c(0,20000), na.value = "black") +
  theme(plot.title = element_text(hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

Buradaki kodlara github adresinden ulaşabilirsiniz. Bir problem halinde bana da ulaşabilirsiniz, birlikte çözmeye çalışabiliriz.