Arkadaşlar,

Veri görselleştirme dünyasında bildiğimiz yolların sonuna geldik ve şimdi kendi patikalarımızı yaratma zamanı. ggplot2 ile attığımız sağlam temellerin üzerine, her biri farklı bir hikaye anlatma biçiminde uzmanlaşmış, niş ama bir o kadar da güçlü araçlarla dolu bir gökdelen inşa edeceğiz.

Bu atölyede, standart grafiklerin ötesine geçerek alet çantamıza çok daha özel ve etkileyici araçlar ekleyeceğiz. Amacımız, veriyi sadece göstermek değil, onunla bir sanat eseri yaratmak!

Atölye Menümüz: Sihirli Aletler

İşte atölye boyunca masamızın üzerinde olacak o sihirli aletler:

Akışları ve Bağlantıları Anlatmak: ggalluvial paketi ile Sankey grafikleri çizeceğiz. Bir sürecin adımları arasındaki geçişleri, müşteri segmentlerinin zaman içindeki değişimini veya herhangi bir sistemdeki akışları bir nehir gibi görselleştireceğiz.

Hiyerarşileri ve Oranları Resmetmek: treemapify paketi ile o karmaşık hiyerarşileri ve iç içe geçmiş oranları, anlaşılması kolay ve estetik Ağaç Haritaları’na (Treemaps) dönüştüreceğiz. Bütünü ve parçalarını tek bir bakışta görebilmek hiç bu kadar şık olmamıştı!

Coğrafi Hikayeleri Canlandırmak: leaflet paketi ile verilerimizi bir dünya haritası üzerine taşıyarak onlara coğrafi bir ruh katacağız. Kullanıcının keşfedebileceği, yakınlaşıp uzaklaşabileceği interaktif haritalar ile verinin nerede olduğunu anlatacağız.

Grafiklere Hayat Vermek: Ve son olarak, ggplot2 ile yarattığımız o güzel statik grafikleri alıp, plotly ile onlara interaktivite, gganimate ile de hareket kazandırarak onları yaşayan, nefes alan birer veri hikayesine dönüştüreceğiz!

Hazır mısın?

Bu bölümün sonunda, elindeki her bir veri setine baktığında “Bunu en etkileyici şekilde nasıl anlatabilirim?” sorusuna verecek birden çok yaratıcı cevabın olacak.

Şimdi kollarımızı sıvayalım ve ilk aletimiz olan ggalluvial ile veri nehirlerinde bir yolculuğa çıkalım!

1. Veri Nehirleri Çizmek: ggalluvial ile Akışları Görselleştirme

Atölyemizin ilk durağında, kategorik veriler arasındaki akışları ve bağlantıları görselleştirmek için kullanılan güçlü bir aracı, ggalluvial paketini öğreneceğiz.

Peki, Alluvial veya Sankey diyagramları nedir?

Bu grafikleri, verinin bir noktadan diğerine nasıl aktığını gösteren nehirler gibi düşünebilirsin. Örneğin:

göstermek için mükemmeldirler. Kısacası, “Nereden geldi, nereye gitti?” sorusunun en estetik cevabıdır bu grafikler.

Kurulum ve Hazırlık

Bu bölümü hazırlarken harika bir dersle karşılaştık: ggalluvial paketinin yeni versiyonlarında, daha önce içinde bulunan titanic_long veri seti kaldırılmış. Bu, veri bilimi dünyasında çok normal bir durumdur. İyi bir analist, bu gibi durumlarda pes etmez, çözüm üretir. Biz de şimdi tam olarak bunu yapıyoruz: İhtiyacımız olan veriyi, R’ın temelindeki Titanic veri setinden kendimiz üreteceğiz!

Ustalık İpucu: ‘Geniş’ Veriden ‘Uzun’ Veriye Yolculuk - ggalluvial Neden Özel Bir Format İster?

Grafiği çizmeden önce cevaplamamız gereken çok önemli bir soru var: Neden R’daki standart Titanic veri setini doğrudan kullanamadık da onu to_lodes() ile dönüştürmek zorunda kaldık?

1. “Geniş” (Wide) Format - Standart Hali:

Önce R’daki orijinal Titanic verisinin dönüştürülmüş haline bakalım:

library(tidyverse)
titanic_genis <- as.data.frame(Titanic)
head(titanic_genis)

Bu formata “geniş format” denir. Her bir satır, kategorilerin benzersiz bir kombinasyonunu (Sınıf, Cinsiyet, Yaş, Hayatta Kalma) ve bu kombinasyona kaç kişinin dahil olduğunu (Freq) gösterir. Bu format, özet tablolar ve bazı analizler için harikadır.

Ancak bir AKIŞI görselleştirmek için uygun değildir. ggplot’a bu tabloyla, “Önce Class’ı, sonra Sex’i eksen olarak koy ve aralarındaki bağlantıyı çiz” demenin doğrudan bir yolu yoktur. ggplot hangi frekansın nereden nereye aktığını bilemez.

2. “Uzun” (Lodes) Format - ggalluvial’ın Sevdiği Hali:

İşte to_lodes() fonksiyonunun yarattığı sihirli format:

library(ggalluvial)
# Bu kod bloğu sadece gösterim amaçlıdır, asıl işlem aşağıda yapılacak.
titanic_uzun_yeni_ornek <- to_lodes(titanic_genis, key = "x", value = "stratum", 
                                    id = "alluvium", axes = 1:4)
head(titanic_uzun_yeni_ornek)

Bu formata “uzun format” veya ggalluvial dilinde “lodes formatı” denir. Farkları görelim:

-alluvium: Bu, en kritik sütundur. Her bir orijinal akışa (örneğin ‘1. Sınıf, Erkek, Yetişkin, Hayatta Kalanlar’ grubu) verilen benzersiz bir kimlik kartı gibidir. ggalluvial bu kimlik kartını takip ederek nehrin bir eksenden diğerine nasıl akması gerektiğini anlar.

-x: Grafiğimizdeki dikey eksenleri temsil eder. Yani “1. durak (Class)”, “2. durak (Sex)” gibi…

-stratum: Bu duraklardaki kategorilerin kendisidir (‘1st’, ‘Male’, ‘Yes’ gibi).

-Freq: Bu kimlik kartına sahip akışın kalınlığını belirler.

Kısacası, to_lodes() fonksiyonu, özetlenmiş “geniş” veriyi alıp, her bir akışa bir kimlik kartı (alluvium) atayarak ve her adımı (x, stratum) tek tek satırlara yazarak, ggplot’un anlayabileceği bir “yol tarifine” dönüştürür. İşte bu yüzden bu dönüşüm, Alluvial diyagramları çizebilmemiz için zorunludur!

İlk Nehrimizi Çizelim: Titanic Veri Setini Baştan Yaratmak

Artık neden yaptığımızı bildiğimize göre, nasıl yapıldığını gösteren nihai kodumuza geçebiliriz.

# --- ADIM 1: Kütüphaneleri Yükle ---
library(tidyverse)
library(ggalluvial)

# --- ADIM 2: Veriyi Hazırla ---
# R'da yerleşik olan `Titanic` veri setini bir veri çerçevesine dönüştürelim.
titanic_genis <- as.data.frame(Titanic)

# Şimdi bu "geniş" formatı, `ggalluvial`'ın sevdiği "uzun" formata çevirelim.
titanic_uzun_yeni <- to_lodes(titanic_genis,
                             key = "x",           # Eksenler sütununun adı 'x' olsun
                             value = "stratum",     # Kategori sütununun adı 'stratum' olsun
                             id = "alluvium",     # Akış ID'si sütununun adı 'alluvium' olsun
                             axes = 1:4)          # İlk 4 sütunu eksen olarak kullan

# --- ADIM 3: Grafiği Çiz ---
# Artık kendi ürettiğimiz "uzun" veri ile grafiğimizi çizebiliriz.
ggplot(data = titanic_uzun_yeni,
       aes(x = x, 
           stratum = stratum, 
           alluvium = alluvium, 
           y = Freq, # Akışın kalınlığını 'Freq' sütunu belirleyecek
           fill = stratum, 
           label = stratum)) +
  geom_flow(stat = "alluvium", lode.guidance = "forward", color = "darkgray") +
  geom_stratum() +
  geom_text(stat = "stratum", size = 3, color = "black") +
  labs(
    title = "Titanic Yolcularinin Hayatta Kalma Akisi",
    subtitle = "Sinif, Cinsiyet, Yas ve Hayatta Kalma Durumu Arasindaki Iliski",
    x = "Degisken",
    y = "Yolcu Sayisi"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

Ustalık Dokunuşu: Rengi Hikayenin Odağına Göre Değiştirmek

Oluşturduğumuz ilk grafik genel akış yapısını göstermekte başarılıydı. Ancak, belirli bir başlangıç grubunun (örneğin 1. Sınıf yolcularının) akıbetini takip etmek imkansızdı.

Çözüm, ggplot’un en güçlü özelliklerinden birinde yatar: estetikleri (aes) verideki farklı sütunlara atayabilmek. Şimdi çizeceğimiz grafiğin bir “hafızası” olmasını ve bir akışın başlangıç noktasını unutmamasını sağlayacağız.

Akışları Başlangıç Noktasına Göre Renklendirme (Mevkilerin Kaderi)

Bu grafikte soracağımız soru şudur: “Her bir mevkiden yola çıkan yolcuların akıbeti ne oldu?”

# Kütüphaneleri ve veriyi bir önceki adımdan zaten hazırlamıştık,
# ama bu bloğun tek başına çalışabilmesi için tekrar ekleyelim.
library(tidyverse)
library(ggalluvial)
titanic_genis <- as.data.frame(Titanic)
titanic_uzun_yeni <- to_lodes(titanic_genis, key = "x", value = "stratum", id = "alluvium", axes = 1:4)

# Her bir akış grubuna ('alluvium'), o grubun başlangıç sınıfını içeren yeni bir sütun ekleyelim.
titanic_renk_sinif <- titanic_uzun_yeni %>%
  group_by(alluvium) %>%
  mutate(BaslangicSinifi = first(stratum)) %>%
  ungroup()

# Şimdi grafiği 'fill' estetiğini bu yeni sütuna bağlayarak çizelim!
ggplot(data = titanic_renk_sinif,
       aes(x = x, 
           stratum = stratum, 
           alluvium = alluvium, 
           y = Freq,
           fill = BaslangicSinifi, # Rengi artık başlangıç sınıfı belirliyor!
           label = stratum)) +
  geom_flow(stat = "alluvium", lode.guidance = "forward") +
  geom_stratum(color = "black") + # Katmanların kenarlıklarını belirginleştirelim
  geom_text(stat = "stratum", size = 3.5, color = "black") +
  labs(
    title = "Titanic'teki Mevkilerin Kaderi",
    subtitle = "Akislar, yolcularin baslangictaki sinifina gore renklendirilmistir",
    x = "Degisken",
    y = "Yolcu Sayisi",
    fill = "Baslangic Sinifi" 
  ) +
  theme_minimal(base_size = 14) # Genel yazı boyutunu biraz büyütelim

İşte bu! Şimdi grafiği tekrar dikkatle okuyalım:

  • Bu grafiği yorumlarken, lejanttaki (Başlangıç Sınıfı) kategori isimleri ile akışların renklerini eşleştirmelisiniz.

  • Mürettebatı (Crew) temsil eden akışın (lejantta mor renkli) neredeyse tamamının nasıl ‘No’ (Hayatta Kalamadı) havuzuna aktığını net bir şekilde görebilirsiniz.

  • Birinci Sınıfı (1st) temsil eden akışın (lejantta kırmızı/pembe renkli) ne kadar büyük bir kısmının ‘Yes’ (Hayatta Kaldı) havuzuna ulaştığını, özellikle de kadınlar (Female) üzerinden geçtiğinde, rahatlıkla takip edebilirsiniz.

  • Üçüncü Sınıfı (3rd) temsil eden akışın (lejantta turkuaz renkli) ise ne kadar ezici bir çoğunlukla ‘No’ havuzuna döküldüğünü görmek artık çok kolay.

Bu grafik, artık sadece bir akış şeması değil, güçlü bir hikaye anlatıcısıdır.

Harika bir başlangıç yaptık! Veri nehirlerimizi başarıyla oluşturduk. Şimdi atölyemizin bir sonraki tezgâhına geçip hiyerarşileri ve oranları treemapify ile nasıl görselleştireceğimize bakalım.

2. Hiyerarşileri ve Oranları Resmetmek: treemapify ile Ağaç Haritaları

Atölyemizin bu bölümünde, “bütünü oluşturan parçaları” ve bu parçaların kendi içindeki hiyerarşisini tek bir bakışta göstermenin en etkili yollarından biri olan Ağaç Haritalarını (Treemaps) oluşturmayı öğreneceğiz.

Ağaç Haritası nedir?

Bir ağaç haritasını, bir araziyi parsellere ayırmak gibi düşünebilirsiniz. Arazinin tamamı, bizim bütün veri setimizi temsil eder. Her bir parsel ise, verimizdeki bir kategoridir. Parselin alanı, o kategorinin bütün içindeki oranını veya büyüklüğünü gösterir.

Bu grafikler, özellikle şu gibi sorulara cevap vermek için mükemmeldir:

A. Kurulum ve Hazırlık

Her zamanki gibi, önce aletimizi tezgâhımıza yerleştirelim.

# Eğer yüklü değilse, bu komut ile paketi yükleyebilirsiniz.
install.packages("treemapify")
# Gerekli kütüphaneleri çağıralım
library(tidyverse)
library(treemapify)

B. İlk Ağaç Haritamız: G20 Ülkelerinin Ekonomik Büyüklükleri

treemapify paketinin en güzel yanlarından biri, içinde G20 adında hazır bir veri setiyle gelmesidir. Bu veri, G20 ülkelerinin ekonomik (GSYİH) ve nüfus bilgilerini içerir.

Haydi bu veriye bir göz atalım:

data(G20)
head(G20)

Şimdi, bu ülkelerin GSYİH’lerine (gdp_mil_usd) göre kapladıkları alanı gösteren basit bir ağaç haritası oluşturalım.

ggplot(G20, 
       aes(area = gdp_mil_usd, 
           fill = region,     
           label = country)) + 
  
  # 1. Katman: Renkli kutuları çiz
  geom_treemap() +
  
  # 2. Katman: 'label' estetiğini kullanarak metinleri çiz
  geom_treemap_text()

Harika! Tek bir katmanla, anında ülkelerin ekonomik büyüklüklerini karşılaştırabileceğimiz bir görsel oluşturduk. ABD’nin, Çin’in ve Japonya’nın kapladığı alanın büyüklüğü hemen göze çarpıyor.

Ustalık Dokunuşu: Hiyerarşi Eklemek ve Görseli Güzelleştirmek

Bu grafiğin asıl gücü, hiyerarşiyi, yani alt grupları gösterebildiğinde ortaya çıkar. Ülkeleri kıtalara (region) göre gruplayarak görselimizi çok daha anlamlı hale getirebiliriz.

Bunun için aes() içine subgroup estetiğini ekleyeceğiz.

ggplot(G20, 
       aes(area = gdp_mil_usd, 
           fill = region, 
           label = country,
           subgroup = region)) + # <- Ustalık dokunuşu burada!
  
  # Temel katman
  geom_treemap() +
  
  # Alt grup kenarlıklarını çizelim
  geom_treemap_subgroup_border(colour = "white", size = 5) +
  
  # Alt grup etiketlerini (kıta isimlerini) ekleyelim
  geom_treemap_subgroup_text(place = "centre", 
                             grow = T, 
                             alpha = 0.5, 
                             colour = "black", 
                             fontface = "italic", 
                             min.size = 0) +
  
  # Ülke etiketlerini daha okunaklı hale getirelim
  geom_treemap_text(colour = "white", 
                    place = "topleft", 
                    reflow = T) +
  
  # Lejantı kapatalım, çünkü renkler zaten grupları belirtiyor
  theme(legend.position = "none") +

  labs(
    title = "G20 Ulkelerinin Ekonomik Buyuklukleri",
    subtitle = "Alanlar GSYIH'yi, gruplar ise kitalari temsil etmektedir",
    caption = "Veri Kaynagı: treemapify paketi"
  )

İşte bu, tam bir “ustalık” eseri!

Neler yaptığımızı özetleyelim:

1.subgroup = region: Bu komutla treemapify’a, ülkeleri önce region sütununa göre bir araya getirmesini, sonra bu grupların içine ülkeleri GSYİH’lerine göre yerleştirmesini söyledik.

2.geom_treemap_subgroup_border(): Bu katman, kıta gruplarının etrafına kalın, beyaz bir çerçeve çizerek onları birbirinden net bir şekilde ayırdı.

3.geom_treemap_subgroup_text(): Her bir kıta grubunun ortasına, o kıtanın ismini soluk ve italik bir şekilde yazdırdık.

4.geom_treemap_text(): Ülke isimlerinin, dikdörtgenlerin sol üst köşesine, daha okunaklı bir şekilde ve kutuya sığacak şekilde yeniden akıtılarak (reflow = T) yazılmasını sağladık.

Artık bu grafik, sadece “hangi ülke ne kadar büyük?” sorusuna değil, aynı zamanda “Asya’daki en büyük ekonomi hangisi?” veya “Avrupa Birliği üyelerinin toplam ekonomik büyüklüğü Amerika kıtasına göre nasıl?” gibi çok daha karmaşık sorulara anında görsel cevaplar veriyor.

treemapify ile hiyerarşileri ve oranları nasıl etkili bir şekilde görselleştireceğimizi öğrendik. Şimdi atölyemizin bir sonraki tezgâhına, verilerimize coğrafi bir ruh katacağımız leaflet’e geçmeye hazırız.

3. Coğrafi Hikayeler Anlatmak: leaflet ile İnteraktif Haritalar

Şimdiye kadar yaptığımız tüm görselleştirmeler, ne kadar harika olsalar da, statik bir tuval üzerindeydiler. Peki ya verilerimizi yaşayan, nefes alan, kullanıcının keşfedebileceği bir dünya haritası üzerine taşıyabilseydik?

İşte leaflet paketi tam olarak bunu yapıyor. leaflet, R’ın gücünü, en popüler açık kaynaklı interaktif harita kütüphanelerinden biri olan Leaflet.js ile birleştiren bir köprüdür. Bu paket sayesinde, sadece birkaç satır kodla, kullanıcıların yakınlaşıp uzaklaşabileceği, üzerine tıklayarak bilgi alabileceği, farklı katmanlar ekleyebileceği dinamik haritalar oluşturabiliriz.

leaflet’in mantığı, ggplot2’dan biraz farklıdır. ggplot2’da katmanları + operatörü ile eklerken, leaflet’te bu işi “pipe” operatörü (%>%) ile, adeta bir boru hattı döşer gibi yaparız.

Kurulum ve Hazırlık

Her zamanki gibi, önce aletimizi tezgâhımıza yerleştirelim.

# Eğer yüklü değilse, bu komut ile paketi yükleyebilirsiniz.
install.packages("leaflet")
# Gerekli kütüphaneleri çağıralım
library(tidyverse)
library(leaflet) # Kahramanımız sahnede!

İlk Haritamız: Dünyaya Merhaba De!

leaflet ile harita oluşturmak iki temel adımdan oluşur:

1.leaflet() fonksiyonu ile boş bir harita tuvali oluşturmak. 2.addTiles() katmanı ile bu tuvalin üzerine bildiğimiz o dünya haritasını (genellikle OpenStreetMap) eklemek.

leaflet() %>%
  addTiles()

İşte bu kadar! Sadece iki komutla, R Markdown dosyanızın içinde tamamen interaktif, kaydırılabilir ve yakınlaştırılabilir bir dünya haritası oluşturdunuz. Bu, leaflet’in temel iskeletidir. Şimdi bu iskeletin üzerine verilerimizi ekleyerek onu canlandırmaya başlayacağız.

Haritaya İşaretçiler (Markers) Eklemek

Haritaları anlamlı kılan şey, üzerlerindeki ilgi çekici noktalardır. leaflet’te bu noktaları* addMarkers() fonksiyonu ile ekleriz.

Örnek olarak, Türkiye’nin en büyük üç şehrinin koordinatlarını kullanarak haritamıza işaretçiler ekleyelim.

# Şehirler ve koordinatları için küçük bir veri çerçevesi oluşturalım.
sehirler <- tibble(
  isim = c("İstanbul", "Ankara", "İzmir"),
  enlem = c(41.0082, 39.9334, 38.4237),
  boylam = c(28.9784, 32.8597, 27.1428)
)

leaflet(data = sehirler) %>%
  addTiles() %>%
  
  # İşaretçileri ekleyelim
  addMarkers(
    lng = ~boylam, # Boylam sütunu (longitude)
    lat = ~enlem,  # Enlem sütunu (latitude)
    popup = ~isim  # İşaretçiye tıklandığında açılacak metin
  )

Harika! Şimdi haritanızın üzerinde üç tane işaretçi belirdi. Bu işaretçilerden herhangi birine tıkladığınızda, o şehrin ismini gösteren küçük bir pencere (popup) açılacaktır.

Ustalık İpucu:

addMarkers() içindeki ~ (tilde) işaretini fark ettiniz mi? Bu, leaflet’in “Bu değeri doğrudan değil, leaflet() fonksiyonunda belirttiğim veri çerçevesinin içindeki ilgili sütundan al” deme şeklidir. Bu sayede yüzlerce noktayı tek bir komutla haritaya ekleyebiliriz.

Ustalık Dokunuşu: Daireler, Renkler ve Lejantlar

Bazen basit bir işaretçi yeterli olmaz. Bir noktanın sadece konumunu değil, aynı zamanda bir büyüklüğü (nüfus, gelir, vb.) ve bir kategoriyi (bölge, grup, vb.) de göstermek isteyebiliriz.

Bunun için addCircleMarkers() fonksiyonu imdadımıza yetişir. Bu fonksiyon, yarıçapı (radius), rengi (color) ve diğer estetik özellikleri verimizdeki sütunlara bağlamamıza olanak tanır.

Örnek olarak, G20 veri setimizi kullanarak ülkelerin başkentlerini haritada gösterelim. Dairelerin büyüklüğü ülkenin nüfusunu, rengi ise bulunduğu kıtayı temsil etsin.

# Bu kod bloğunun başlığındaki `eval=knitr::is_html_output()` komutu,
# bu bloğun SADECE HTML çıktısı alınırken çalışmasını sağlar.

# Gerekli Kütüphaneler
library(tidyverse)
library(leaflet)

# Veriyi Hazırlama ve Türkçeleştirme
g20_turkce <- G20 %>%
  mutate(
    Kita = case_when(
      region == "Africa" ~ "Afrika", region == "Asia" ~ "Asya",
      region == "Eurasia" ~ "Avrasya", region == "Europe" ~ "Avrupa",
      region == "Middle East" ~ "Orta Doğu", region == "North America" ~ "Kuzey Amerika",
      region == "Oceania" ~ "Okyanusya", region == "South America" ~ "Güney Amerika",
      TRUE ~ region
    ),
    Ulke = case_when(
      country == "United States" ~ "ABD", country == "China" ~ "Çin",
      country == "Germany" ~ "Almanya", country == "Brazil" ~ "Brezilya",
      country == "India" ~ "Hindistan", country == "Australia" ~ "Avustralya",
      country == "South Africa" ~ "Güney Afrika",
      TRUE ~ country
    ),
    EkonomikSinif = case_when(
      econ_classification == "Advanced" ~ "Gelişmiş",
      econ_classification == "Developing" ~ "Gelişmekte Olan",
      TRUE ~ econ_classification
    )
  )

# Koordinatları Ekleme
g20_koordinatli <- g20_turkce %>%
  filter(Ulke %in% 
           c("ABD", "Çin", "Almanya", "Brezilya", "Hindistan", "Avustralya", "Güney Afrika")) %>%
  mutate(
    enlem = case_when(
      Ulke == "ABD" ~ 38.9072, Ulke == "Çin" ~ 39.9042, Ulke == "Almanya" ~ 52.5200,
      Ulke == "Brezilya" ~ -15.8267, Ulke == "Hindistan" ~ 28.6139, Ulke == "Avustralya" ~ -35.2809,
      Ulke == "Güney Afrika" ~ -25.7479
    ),
    boylam = case_when(
      Ulke == "ABD" ~ -77.0369, Ulke == "Çin" ~ 116.4074, Ulke == "Almanya" ~ 13.4050,
      Ulke == "Brezilya" ~ -47.9218, Ulke == "Hindistan" ~ 77.2090, Ulke == "Avustralya" ~ 149.1300,
      Ulke == "Güney Afrika" ~ 28.2293
    )
  )

# Renk Paleti ve Harita
renk_paleti <- colorFactor(palette = "viridis", domain = g20_koordinatli$Kita)
leaflet(data = g20_koordinatli) %>%
  addProviderTiles(providers$CartoDB.Positron) %>%
  addCircleMarkers(
    lng = ~boylam, lat = ~enlem, radius = ~hdi * 30, color = ~renk_paleti(Kita),
    stroke = FALSE, fillOpacity = 0.8,
    popup = paste(
      "<b>Ülke:</b>", g20_koordinatli$Ulke, "<br>",
      "<b>Ekonomik Sınıflandırma:</b>", g20_koordinatli$EkonomikSinif, "<br>",
      "<b>Nüfus (milyon):</b>", g20_koordinatli$population_mil, "<br>",
      "<b>GSYİH (milyar $):</b>", round(g20_koordinatli$gdp_mil_usd / 1000, 1), "<br>",
      "<b>İGE:</b>", g20_koordinatli$hdi
    )
  ) %>%
  addLegend(pal = renk_paleti, values = ~Kita, opacity = 1, title = "Kıta", position = "bottomright")

İşte bu! Artık sadece bir haritamız yok; üzerinde keşfedilecek bir hikaye var. Kullanıcılar artık dairelerin büyüklüğüne bakarak ülkelerin insani gelişmişlik seviyelerini, renklerine bakarak kıtalarını ve üzerine tıklayarak detaylı ekonomik bilgilerini görebilirler.

leaflet ile statik verileri, yaşayan ve keşfe davet eden coğrafi hikayelere dönüştürmenin ilk adımını attık. Şimdi atölyemizin son tezgahlarına doğru ilerleyerek, bu interaktiviteyi tüm ggplot grafiklerimize nasıl uygulayacağımızı öğreneceğiz.

4. Grafiklere Hayat Vermek: plotly ile İnteraktivite

Şimdiye kadar ggplot2 ile oluşturduğumuz tüm o harika grafiklerin bir eksiği vardı: onlar birer fotoğraftı. Üzerine gelip detayları göremiyor, ilginizi çeken bir alanı yakınlaştıramıyordunuz.

İşte plotly paketi bu sorunu çözmek için var. plotly, ggplotly() adında sihirli bir fonksiyona sahiptir. Bu fonksiyon, oluşturduğunuz herhangi bir ggplot nesnesini alır ve onu tek bir komutla, tamamen interaktif bir web grafiğine dönüştürür.

A. Kurulum ve Hazırlık

install.packages("plotly")
library(tidyverse)
library(plotly)

# Örnek veri setimiz için gapminder'ı da çağıralım.
library(gapminder)

B. Sihirli Dönüşüm: ggplotly()

Önce, gapminder veri setini kullanarak basit bir ggplot grafiği oluşturalım. 2007 yılındaki ülkelerin kişi başına düşen gelir (gdpPercap) ve yaşam süresi (lifeExp) arasındaki ilişkiyi inceleyelim. Noktaların büyüklüğü de nüfusu (pop) temsil etsin.

# Gerekli kütüphaneleri çağıralım (eğer daha önce çağrılmadıysa)
library(tidyverse)
library(ggplot2)
library(gapminder)

# Statik ggplot grafiğimizi, lejant formatlaması eklenmiş haliyle oluşturalım
p_formatli <- ggplot(filter(gapminder, year == 2007), 
            aes(x = gdpPercap, y = lifeExp, color = continent, size = pop)) +
  geom_point(alpha = 0.7) +
  
  # X eksenini de tutarlılık için formatlayalım
  scale_x_log10(labels = scales::comma) +
  
  # --- İŞTE SİHİRLİ DOKUNUŞ BURADA ---
  # Boyut lejantındaki etiketleri virgüllü sayı formatına çeviriyoruz.
  scale_size_continuous(labels = scales::comma) +
  
  labs(
    title = "2007 Yılında Ülkelerin Yaşam Süresi ve GSYİH İlişkisi",
    x = "Kişi Başına Düşen GSYİH (Logaritmik Ölçek)",
    y = "Ortalama Yaşam Süresi",
    color = "Kıta",
    size = "Nüfus"
  ) +
  theme_minimal()

# Grafiğin son, mükemmel halini görelim
p_formatli

Şimdi sihri yapma zamanı. Tek bir komutla bu statik fotoğrafı, yaşayan bir nesneye dönüştürelim.

ggplotly(p_formatli, tooltip = c("x", "y", "color", "size"))

İşte bu kadar! Eğer bu raporu HTML olarak görüntülüyorsanız, artık grafiğin üzerine fareyle gelerek her bir noktanın tüm detaylarını (GSYİH, yaşam süresi, nüfus, kıta) görebilir, sağ üstteki araç çubuğuyla belirli bir alanı yakınlaştırabilir ve grafiği keşfe çıkabilirsiniz.

C. Ustalık Dokunuşu: Bilgi Pencerelerini Özelleştirmek

ggplotly otomatik olarak harika bilgi pencereleri (tooltips) oluşturur, ancak bazen bu bilgileri daha anlaşılır ve temiz bir formatta sunmak isteyebiliriz.

Bunu yapmak için, orijinal ggplot’umuza text adında özel bir estetik ekleyeceğiz. Bu text estetiği, plotly tarafından bilgi penceresi metni olarak kullanılacaktır.

p_ozel <- ggplot(filter(gapminder, year == 2007), 
                 aes(x = gdpPercap, y = lifeExp, color = continent, size = pop,
                     # --- Ustalık Dokunuşu Burada ---
                     # Her nokta için özel bir metin oluşturuyoruz.
                     text = paste("<b>Ülke:</b>", country,
                                  "<br><b>Nüfus:</b>", round(pop/1000000, 1), "milyon",
                                  "<br><b>Yaşam Süresi:</b>", round(lifeExp, 1), "yıl"))) +
  geom_point(alpha = 0.7) +
  scale_x_log10() +
  labs(title = "2007 Yılında Ülkelerin Yaşam Süresi ve GSYİH İlişkisi",
       x = "Kişi Başına Düşen GSYİH (Logaritmik Ölçek)", y = "Ortalama Yaşam Süresi") +
  theme_minimal() +
  theme(legend.position = "none") # Lejantı kapattık çünkü tüm bilgi tooltip'te

# ggplotly'e bu sefer özel "text" estetiğini kullanmasını söylüyoruz.
ggplotly(p_ozel, tooltip = "text")

Şimdi noktaların üzerine geldiğinizde, çok daha temiz, formatlanmış ve tam olarak sizin istediğiniz bilgileri içeren pencereler görüyorsunuz.

5. Hareketli Hikayeler: gganimate ile Animasyon Sanatı

Atölyemizin son tezgâhında, veri görselleştirmeyi bir adım daha ileri taşıyıp, grafiklerimize zaman boyutu ekleyeceğiz. gganimate, ggplot2’nun gramerini genişleterek, verinin bir değişken (genellikle zaman) üzerindeki değişimini akıcı animasyonlara dönüştürmemizi sağlar.

A. Kurulum ve Hazırlık

gganimate, animasyonları GIF formatında oluşturmak için gifski paketine ihtiyaç duyar.

install.packages("gganimate")
install.packages("gifski")
library(gganimate)
library(gifski)

B. İlk Animasyonumuz: Yıllar İçinde Dünya

Az önce oluşturduğumuz gapminder grafiği sadece 2007 yılını gösteriyordu. Peki ya 1952’den 2007’ye kadar tüm bu ülkelerin yolculuğunu bir film gibi izleyebilseydik?

gganimate ile bu çok kolay. Tek yapmamız gereken, statik ggplot kodumuza birkaç sihirli katman eklemek.

# Temel ggplot grafiğimizi bu sefer yıl filtresi olmadan oluşturuyoruz.
# scales paketinin içindeki 'comma' fonksiyonuna ihtiyacımız olacak.
# Paketi library() ile çağırmak yerine, `scales::comma` şeklinde doğrudan
# kullanmak, kodun daha anlaşılır olmasını sağlayan bir "ustalık" pratiğidir.

# Gerekli kütüphaneler
library(tidyverse)
library(ggplot2)
library(gapminder)
library(gganimate)
library(gifski)

# Temel ggplot grafiğimizi oluşturuyoruz
anim_formatli <- ggplot(gapminder, aes(x = gdpPercap, y = lifeExp, color = continent, size = pop)) +
  geom_point(alpha = 0.7) +
  
  # --- 1. Ustalık Dokunuşu: X Eksenini Formatlamak ---
  scale_x_log10(
    labels = scales::comma # Etiketleri virgüllü sayı formatına çevir
  ) +
  
  # --- 2. Ustalık Dokunuşu: Lejantı Formatlamak ---
  scale_size_continuous(
    labels = scales::comma # Boyut lejantındaki etiketleri de virgüllü sayı formatına çevir
  ) +
  
  theme_minimal() +
  
  # --- gganimate Sihri ---
  transition_time(year) +
  labs(
    title = "Yıl: {frame_time}",
    x = "Kişi Başına Düşen GSYİH (Logaritmik Ölçek)",
    y = "Ortalama Yaşam Süresi",
    color = "Kıta",
    size = "Nüfus"
  ) +
  shadow_wake(wake_length = 0.1, alpha = FALSE)

# Animasyonu render edelim
anim_formatli

İşte bu kadar! Kod çalıştığında, RStudio’nun “Viewer” sekmesinde yıllar içinde ülkelerin nasıl bir gelişim gösterdiğini, bazı Asya ülkelerinin nasıl inanılmaz bir atılım yaptığını ve genel olarak dünyanın nasıl daha sağlıklı ve zengin bir yer haline geldiğini gösteren bir animasyon (GIF) oluşacak.

Bu animasyon, onlarca statik grafiğin anlatamayacağı bir hikayeyi, sadece 10 saniye içinde, çok daha etkili bir şekilde anlatır.