Önce özete göz atDersin sonundaki özet, okumaya başlamadan önce yol haritası olarak.
- Bir grafik, verideki değerleri konum, uzunluk, açı, alan ya da renk gibi görsel özelliklerle kodlar; Cleveland ile McGill'e göre ortak bir eksen üzerindeki konum en doğru okunan kodlamadır, alan ve renk tonu ise daha alt sıralardadır.
- Cleveland ile McGill, pasta ve bölünmüş çubuk grafikler gibi yaygın grafiklerde köklü değişiklikler gerektiğini savundu ve yerlerine nokta grafiklerini önerdi; Heer ile Bostock, grafik algısı deneylerinin kitle kaynaklı olarak tekrarlanabildiğini gösterdi.
- Python'da matplotlib grafiği adım adım çizer; John Hunter'ın beyin dalgası verileriyle çalışırken başlattığı bu kütüphane, MATLAB'ın çizim yeteneklerini taklit ederek doğdu. R'daki ggplot2 ise Wickham'ın katmanlı grafik dilbilgisine dayanır ve grafiği estetik eşlemeler ve katmanlarla kurar.
- Varsayılan ayarlar veriyi bilmez: yıllık bir seride yarım yıllar gösterebilir ya da uygun olmayan bir eksen seçebilir; çubuk grafikte eksen sıfırdan başlamalı, logaritmik ölçek oranları, küçük çoklular grupları karşılaştırmayı kolaylaştırır.
- Keşifsel grafikler analizcinin kendisi içindir ve veri hatalarını bulmaya yarar; açıklayıcı grafikler ise bulguyu söyleyen bir başlık, açık eksen etiketleri ve verinin kaynağını ve indirme tarihini gösteren bir notla birlikte hazırlanmalıdır.
Öğrenme çıktıları
- Hatırlama — Görsel kodlamayı, temel algısal görevi, grafik dilbilgisini, estetik eşlemeyi, küçük çokluları ve keşifsel grafiği tanımlar.
- Anlama — İnsanların bir grafikten sayısal bilgiyi hangi görsel öğeler aracılığıyla ne doğrulukla okuduğunu ve bunun grafik türü seçimini nasıl yönlendirdiğini açıklar.
- Uygulama — Python'da matplotlib ile ve R'da ggplot2 ile zaman serisi, çubuk, dağılım ve küçük çoklu grafikleri çizer, eksenleri ve etiketleri düzenler ve grafiği bir dosyaya kaydeder.
- Değerlendirme — Cleveland ile McGill'in ve Heer ile Bostock'un bulgularından yararlanarak bir iktisat grafiğinin okura doğru bilgiyi verip vermediğini değerlendirir ve daha iyi bir alternatif önerir.
Sezgi
Açılış
Bir politika raporunda iki grafik var. Birincisinde, ülkelerin bütçe harcamalarındaki payları renkli bir pasta grafiğiyle gösterilmiş; eğitimin payı ile sağlığın payı hangisi büyük, bir türlü ayırt edilemiyor. İkincisinde, aynı paylar yatay bir eksen üzerinde sıralanmış noktalarla gösterilmiş; hangi kalemin büyük olduğu ve ne kadar büyük olduğu tek bakışta okunuyor. İki grafik aynı sayıları taşıyor, ama okura aynı şeyi söylemiyor.
Grafik, iktisatçının veriyle ilk karşılaşmasında da, bulgusunu başkalarına anlatırken de en güçlü aracıdır. Bir tablo yüz sayıyı dizer; iyi bir grafik, o yüz sayının içindeki eğilimi, kırılmayı ya da aykırı değeri bir anda gösterir. Ama grafik aynı zamanda yanıltmaya da en açık araçtır: eksen seçimi, ölçek, renk ve grafik türü, okurun gözünün neyi göreceğini belirler.
Bu ders, iki dilin grafik çizme araçlarını ve bir grafiğin okura ne söyleyeceğini belirleyen algı ilkelerini ele alıyor. Amaç, yalnızca grafik çizmek değil, okunabilir ve dürüst grafik çizmektir.
Hikâye — Beyin dalgalarından bir grafik kütüphanesine
John Hunter, beyin dalgalarını, yani elektroensefalografi verilerini inceleyen bir araştırmacıydı. Yıllar sonra matplotlib'in belgelerinde yer alan kısa tarihçesinde anlattığına göre, yıllarca veri analizi ve görselleştirme için yalnızca MATLAB kullanmıştı; MATLAB güzel görünen grafikleri kolayca çizmekte başarılıydı. EEG verileriyle çalışmaya başladığında, verileriyle etkileşim kuracak uygulamalar yazması gerekti ve MATLAB'da bir analiz uygulaması geliştirdi. Uygulama veri tabanlarıyla, internet sunucularıyla ve karmaşık veri yapılarıyla uğraşacak kadar büyüdükçe, MATLAB'ın bir programlama dili olarak sınırlarına takıldı ve Python'da baştan başlamaya karar verdi.
Hunter'a göre Python, bir programlama dili olarak MATLAB'ın eksiklerini fazlasıyla kapatıyordu; ama iki boyutlu grafikler için uygun bir paket bulamıyordu. Aradığı paketin yayın kalitesinde grafikler üretmesini, metinlerin düzgün görünmesini, TeX belgelerine eklenebilecek çıktılar vermesini, bir kullanıcı arayüzüne yerleştirilebilmesini ve kodunun anlaşılıp genişletilebilecek kadar sade olmasını istiyordu. Hepsini karşılayan bir paket bulamayınca, kendi ifadesiyle, kendine saygısı olan her Python programcısının yapacağını yaptı: kollarını sıvadı ve işe girişti. Bilgisayar grafiği konusunda gerçek bir deneyimi olmadığı için, MATLAB'ın çizim yeteneklerini taklit etmeye karar verdi. Bunun bir avantajı da, MATLAB deneyimi olan pek çok kişinin Python'da hızla grafik çizmeye başlayabilmesiydi.
Hunter'ın başlattığı matplotlib, bugün Python'da en yaygın kullanılan grafik kütüphanesidir. R dünyasında ise başka bir yol izlendi. Hadley Wickham, 2010'da Journal of Computational and Graphical Statistics'te yayımlanan «A Layered Grammar of Graphics», yani «Katmanlı Bir Grafik Dilbilgisi» başlıklı makalesinde, Leland Wilkinson'ın grafik dilbilgisi fikrine dayanan ggplot2 paketini anlattı. Wickham'a göre bir grafik dilbilgisi, bir grafiğin bileşenlerini kısaca tanımlamayı sağlıyor ve dağılım grafiği gibi adı konmuş grafiklerin ötesine geçip, istatistiksel grafiklerin altında yatan derin yapıyı görmeye olanak veriyordu.
İki kütüphane, iki farklı yaklaşımı temsil eder. matplotlib, grafiği adım adım çizmeye dayanır: önce bir çizim alanı açılır, sonra çizgiler, noktalar ve etiketler tek tek eklenir. ggplot2 ise grafiği bir cümle gibi kurar: hangi verinin, hangi değişkenin hangi görsel öğeye eşleneceği ve hangi geometrik biçimle çizileceği söylenir. İkisi de iyi grafikler üretebilir; önemli olan, hangi aracın kullanıldığından çok, grafiğin okura ne söylediğidir.
Kavram
Bir grafiğin temel işlemi şudur.
Okurun bir grafikten değeri geri çıkarması da bir işlemdir.
Grafikleri bileşenlerine ayıran yaklaşımın adı şudur.
Dilbilgisinin merkezindeki kavram şudur.
Birçok grubu karşılaştırmanın etkili bir yolu şudur.
Son olarak, grafiklerin iki farklı amacı vardır.
Veri ve kanıt
Cleveland ile McGill'in sıralamasında, ortak bir eksen üzerindeki konum en doğru okunan kodlamadır; uzunluk, yön ve açı onu izler; alan, hacim ve renk tonu ise daha alt sıralardadır. Bu sonuç, açılıştaki iki grafiğin neden farklı okunduğunu açıklar. Pasta grafik, değerleri açı ve alanla kodlar ve okur benzer büyüklükteki iki dilimi ayırt etmekte zorlanır. Nokta grafiği ise değerleri ortak bir eksen üzerindeki konumla kodlar ve okur farkı hemen görür.
Heer ile Bostock'un çalışması, Cleveland ile McGill'in yirmi beş yıl önceki bulgularının, çok daha büyük ve farklı bir katılımcı grubuyla tekrarlanmasıdır. Bir bulgunun farklı bir örneklemle, farklı bir yöntemle yeniden sınanması, veri çekme ve temizleme derslerinde öne çıkan tekrarlanabilirlik kaygısının görselleştirme alanındaki karşılığıdır. İki çalışmanın birlikte verdiği mesaj, grafik tasarımının zevk meselesi olmadığıdır: bazı kodlamalar ölçülebilir biçimde daha doğru okunur.
Yaygın yanlış«Pasta grafik, payları göstermenin en iyi yoludur, çünkü bütünün parçalarını gösterir.»
Pasta grafik bütünün parçalarını gösterir, ama değerleri açı ve alanla kodlar; Cleveland ile McGill'in sıralamasında bu kodlamalar, ortak bir eksen üzerindeki konum ya da uzunluktan daha az doğru okunur. Özellikle birbirine yakın paylar ya da çok sayıda dilim söz konusu olduğunda, sıralanmış bir nokta ya da çubuk grafiği çoğu zaman daha doğru okunur.
Yaygın yanlış«Grafik kütüphanesinin varsayılan ayarları her zaman okunabilir bir grafik üretir.»
Varsayılan ayarlar genel amaçlıdır ve verinin özelliklerini bilmez. Örneğin yıllık bir seride yatay eksene 2019,5 gibi anlamsız ara değerler koyabilir, uygun olmayan bir eksen aralığı seçebilir ya da çok sayıda çizgiyi birbirinden ayırt edilemeyen renklerle çizebilir. Her grafik, eksenleri, etiketleri ve başlığıyla birlikte gözden geçirilmelidir.
Neden önemli?
İktisatçının sonuçları, çoğu zaman bir grafik aracılığıyla karar vericilere ve kamuoyuna ulaşır. Bir merkez bankası raporundaki enflasyon grafiği, bir bakanlığın sunumundaki büyüme grafiği ya da bir gazete haberindeki işsizlik grafiği, okurun ekonomiyi nasıl algıladığını belirler. Dürüst ve okunabilir grafikler çizmek, bu yüzden bir tasarım becerisi olmanın ötesinde bir sorumluluktur.
Grafikler analizin kendisi için de vazgeçilmezdir. Önceki derste gördüğümüz biçim hatası gibi bir aykırı değer, bir tabloda gözden kaçabilir, ama bir çizgi grafiğinde hemen göze çarpar. Veriyi temizledikten sonra, onu modellemeye geçmeden önce birkaç keşifsel grafik çizmek, iyi bir alışkanlıktır.
Enflasyonun hızla tırmandığı yıllarda Türkiye'nin fiyat, faiz ve kur serilerinin grafiklerini çizerken ölçek seçimi özellikle önemlidir. Yüzde 20 ile yüzde 80 arasında değişen bir seriyi, yüzde 2 ile yüzde 8 arasında değişen başka bir ülkenin serisiyle aynı eksende çizmek, ikinci ülkenin hareketlerini görünmez kılar. Küçük çoklular ve logaritmik ölçek gibi araçlar, bu tür karşılaştırmaları okunabilir hâle getirir.
Model
Çözümlü örnek — İlk zaman serisi grafiği
Önceki derste Dünya Bankası'ndan çektiğimiz Türkiye büyüme serisini, 2019'dan 2023'e 1,3, 1,8, 11,8, 5,4 ve 5,0, bir çizgi grafiğiyle gösterelim. matplotlib'de önce bir çizim alanı açar, sonra çizgiyi ve etiketleri ekleriz.
import matplotlib.pyplot as pltfig, ax = plt.subplots(figsize=(6, 4))ax.plot(df["yil"], df["buyume"], marker="o")ax.set_title("Türkiye, yıllık reel GSYH büyümesi (%)")ax.set_ylabel("Yüzde")fig.savefig("buyume.png", dpi=150, bbox_inches="tight")
fig, grafiğin bütününü; ax ise içindeki çizim alanını temsil eder. marker="o", her gözlemi bir noktayla işaretler; yıllık gibi seyrek verilerde noktalar, çizginin yalnızca gözlemleri birleştirdiğini hatırlatır. savefig, grafiği bir dosyaya kaydeder; dpi çözünürlüğü, bbox_inches="tight" kenar boşluklarını ayarlar.
Bu satırlar matplotlib'in 3.9 sürümüyle çalıştırıldığında, grafik doğru çizildi, ama yatay eksende 2019.0, 2019.5, 2020.0 gibi değerler göründü. Program yılları sürekli bir sayı gibi ele almış ve yarım yıllar eklemişti; oysa verimizde yarım yıl yoktur. Tek bir satır sorunu çözer.
ax.set_xticks(df["yil"])
Bu satırdan sonra eksende yalnızca 2019, 2020, 2021, 2022 ve 2023 görünür. Varsayılan ayarların veriyi bilmediğinin somut bir örneğidir: her grafik, çizildikten sonra bir kez gözle denetlenmelidir. R'da aynı grafik ggplot2 ile şöyle kurulur.
- R:
ggplot(df, aes(x = yil, y = buyume)) + geom_line() + geom_point() + labs(title = "Türkiye, yıllık reel GSYH büyümesi (%)", y = "Yüzde")
Başlık da bir tasarım kararıdır. «Türkiye, yıllık reel GSYH büyümesi» gibi bir başlık, grafikte neyin gösterildiğini söyler; «Büyüme 2021'deki sıçramadan sonra yüzde 5 civarına indi» gibi bir başlık ise okura grafikten ne çıkarması gerektiğini söyler. Keşifsel grafiklerde birincisi yeterlidir; bir rapora girecek açıklayıcı grafiklerde ikincisi, okurun dikkatini bulguya yönlendirir. Ama bulguyu söyleyen bir başlık, grafiğin gerçekten o bulguyu gösterdiğinden emin olmayı gerektirir: başlık ile çizgi arasındaki uyumsuzluk, okurun güvenini hemen sarsar. Eksen etiketleri de birimleri, örneğin yüzde, milyon lira ya da endeks gibi, açıkça ve kısaltmasız belirtmelidir.
Çözümlü örnek — Sıfır çizgisi ve eksen aralığı
Büyüme ve enflasyon gibi serilerde sıfır, anlamlı bir eşiktir: büyümenin eksiye düşmesi bir daralma demektir. Grafiğe sıfırda ince bir yatay çizgi eklemek, okurun bu eşiği görmesini sağlar.
- Python:
ax.axhline(0, color="gray", linewidth=0.8) - R:
+ geom_hline(yintercept = 0, colour = "gray")
Eksen aralığı ise grafiğin mesajını değiştirebilir. İki bölgenin gelir düzeyleri 100 ve 104 olsun. Çubuk grafikte dikey ekseni 98'den başlatırsak, B'nin çubuğu A'nınkinin yaklaşık üç katı uzunlukta görünür; oysa fark yüzde 4'tür. Çubuk grafikte değer, çubuğun uzunluğuyla kodlanır ve uzunluk sıfırdan başlamazsa okurun gördüğü oran yanlış olur. Önceki kursta gördüğümüz yalan katsayısı, bu çarpıklığın ölçüsüdür.
Çizgi grafikte ise durum farklıdır: değer uzunlukla değil konumla kodlanır ve okur çoğu zaman düzeyden çok değişime bakar. Bir faiz oranının yüzde 8 ile yüzde 9 arasındaki hareketini sıfırdan başlayan bir eksende çizmek, bu hareketi görünmez kılabilir. Kural, grafik türüne göre değişir: çubukta sıfır zorunludur, çizgide eksen, verinin değişim aralığını okunur kılacak biçimde seçilir ve bu seçim okura açıkça gösterilir. Sayılar varsayımdır.
Çözümlü örnek — Pasta yerine sıralı nokta grafiği
Bir bütçede beş kalemin payları, eğitim için yüzde 22, sağlık için 20, sosyal koruma için 19, savunma için 11 ve diğerleri için 28 olsun. Bir pasta grafikte eğitim, sağlık ve sosyal koruma dilimleri neredeyse aynı görünür ve hangisinin büyük olduğu okunamaz. Cleveland ile McGill'in önerisine uyarak, aynı payları sıralanmış bir nokta grafiğiyle gösterelim.
- Python:
s = s.sort_values()ve ardındanax.plot(s.values, s.index, "o") - R:
ggplot(df, aes(x = pay, y = reorder(kalem, pay))) + geom_point()
Her kalem dikey eksende bir satırda, payı ise ortak yatay eksen üzerinde bir noktayla gösterilir. Kalemler paya göre sıralandığı için en büyüğü en üstte, en küçüğü en altta yer alır. Eğitimin sağlıktan, sağlığın sosyal korumadan büyük olduğu ve farkların ne kadar küçük olduğu tek bakışta görülür. Değerler artık konumla kodlanmıştır ve konum, sıralamanın en üstündedir.
R'daki reorder fonksiyonu, kalemleri paylarına göre sıralar; bu adım atlanırsa kalemler alfabetik sırayla dizilir ve sıralamanın sağladığı okunabilirlik kaybolur. Aynı ilke çubuk grafikler için de geçerlidir: kategoriler, doğal bir sıraları yoksa, değerlerine göre sıralanmalıdır. Sayılar varsayımdır.
Çözümlü örnek — Küçük çoklular
Türkiye ile Almanya'nın 2021–2023 enflasyonunu, önceki derste çektiğimiz değerlerle, karşılaştıralım: Türkiye'de oranlar 19,6'dan 72,3'e çıkıp 53,9'a inmiş, Almanya'da 3,1'den 6,9'a çıkıp 5,9'a gerilemişti. İki seriyi aynı grafikte çizersek, Almanya'nın çizgisi sıfıra yakın düz bir çizgi gibi görünür ve 2022'deki artışı fark edilmez. Küçük çoklularla her ülke kendi panelinde çizilir.
- Python:
fig, axes = plt.subplots(1, 2, figsize=(8, 3), sharey=True) - R:
ggplot(df, aes(x = yil, y = enflasyon)) + geom_line() + facet_wrap(~ ulke)
matplotlib'de sharey=True, iki panelin dikey eksenini ortak yapar; ggplot2'de facet_wrap, veri çerçevesindeki ülke değişkenine göre panelleri kendiliğinden oluşturur ve varsayılan olarak ortak eksen kullanır. Ortak eksen, düzeylerin karşılaştırılmasını sağlar: Türkiye'nin enflasyonu Almanya'nınkinin çok üstündedir. Ama ortak eksende Almanya'nın paneli yine düz görünür.
Almanya'nın kendi hareketini görmek istiyorsak, eksenleri serbest bırakırız: ggplot2'de facet_wrap(~ ulke, scales = "free_y"), matplotlib'de sharey=False. Bu kez her panel kendi aralığını kullanır ve Almanya'nın 2022'deki artışı görünür hâle gelir; ama okur artık iki panelin düzeylerini doğrudan karşılaştıramaz ve bunu bilmelidir. Hangi seçeneğin doğru olduğu, grafiğin sorusuna bağlıdır: düzeyler mi, yoksa her ülkenin kendi değişimi mi? Serbest eksen seçildiğinde bunu grafiğin notunda ya da başlığında belirtmek, okurun iki paneli yanlışlıkla aynı ölçekte okumasını önler.
Çözümlü örnek — Logaritmik ölçek
Bir fiyat endeksi on yıl boyunca 100'den 1.000'e, ardından 1.000'den 10.000'e çıksın. Doğrusal bir eksende ilk on yıl neredeyse düz bir çizgi, ikinci on yıl ise dik bir yükseliş gibi görünür. Oysa her iki dönemde de fiyatlar on katına çıkmıştır; artış hızları aynıdır.
- Python:
ax.set_yscale("log") - R:
+ scale_y_log10()
Logaritmik ölçekte eşit aralıklar eşit oranları gösterir: 100'den 1.000'e ve 1.000'den 10.000'e uzanan iki dönem, eşit eğimli iki doğru parçası olarak görünür. Önceki kursta gördüğümüz gibi, logaritmik ölçek, uzun dönemli büyüme ve enflasyon serilerini karşılaştırmak için özellikle uygundur, çünkü okurun gözü eğime, yani büyüme hızına odaklanır.
Logaritmik ölçek kullanırken eksen etiketlerinin bunu açıkça göstermesi gerekir. Okur ölçeğin logaritmik olduğunu fark etmezse, eşit görünen iki artışın aslında çok farklı mutlak büyüklükte olduğunu kaçırabilir. Ayrıca logaritmik ölçek sıfır ya da eksi değerleri gösteremez; büyüme oranı gibi eksiye düşebilen seriler için uygun değildir. Sayılar varsayımdır.
Çözümlü örnek — Dağılım grafiği ve ilişki
İki değişken arasındaki ilişkiyi görmek için dağılım grafiği kullanılır: her gözlem, yatay eksende bir değişkenin, dikey eksende öbürünün değeriyle bir nokta olarak çizilir. Örneğin 81 ilin kişi başına geliri ile işsizlik oranı arasındaki ilişkiye bakalım.
- Python:
ax.scatter(df["gelir"], df["issizlik"], alpha=0.6) - R:
ggplot(df, aes(x = gelir, y = issizlik)) + geom_point(alpha = 0.6)
alpha değeri noktaları yarı saydam yapar; üst üste binen noktalar daha koyu görünür ve verinin nerede yoğunlaştığı anlaşılır. Gelir gibi çarpık dağılan değişkenlerde yatay ekseni logaritmik yapmak, noktaların sol köşede yığılmasını önler.
ggplot2'de bir değişkeni renge eşlemek, örneğin aes içine colour = bolge eklemek, illerin coğrafi bölgelerini de gösterir. Ama renk, Cleveland ile McGill'in sıralamasında alt sıralarda yer alır; çok sayıda rengi ayırt etmek zordur ve renk körlüğü olan okurlar için bazı renk çiftleri aynı görünür. Grup sayısı fazlaysa, renk yerine küçük çoklular daha okunabilir olabilir. Dağılım grafiğinin gösterdiği ilişkinin nedensel olmadığı da unutulmamalıdır: gelir ile işsizlik arasındaki bağı, bölgenin sanayi yapısı gibi üçüncü etkenler belirleyebilir.
Çözümlü örnek — Keşifsel grafikle hata avı
Önceki derste dört ilin işsizlik oranlarından birinin, ondalık ayracın kaybolmasıyla 9,50 yerine 950 okunduğunu görmüştük. Bu hatayı bulmanın en hızlı yolu, veriyi okuduktan hemen sonra bir histogram ya da kutu grafiği çizmektir.
- Python:
df["issizlik"].plot(kind="hist", bins=20) - R:
hist(df$issizlik, breaks = 20)
Histogramda değerlerin neredeyse tamamı sıfır ile yirmi arasında toplanır, tek bir çubuk ise 950 civarında, diğerlerinden çok uzakta durur. Bu grafik hiçbir rapora girmez; yalnızca analizcinin kendisi içindir ve birkaç saniyede çizilir. Keşifsel grafiğin değeri de buradadır: özenle biçimlendirilmesi gerekmez, ama veride bir sorun varsa onu hemen gösterir.
pandas veri çerçevelerinin plot yöntemi, matplotlib'i arka planda kullanarak hızlı keşifsel grafikler çizer; R'ın temel hist ve plot fonksiyonları da aynı işi görür. Veri temizliğinin her aşamasında, birkaç keşifsel grafik çizmek, tablolara bakarak bulunamayacak sorunları görünür kılar. Sayılar varsayımdır.
Çözümlü örnek — Kaynak notu ve kaydetme biçimi
Bir rapora girecek her grafik, verinin nereden geldiğini ve ne zaman çekildiğini göstermelidir. Önceki derste gördüğümüz gibi veriler revize edilir; aylar sonra grafiğe bakan biri, hangi veri sürümünün çizildiğini bilmelidir. matplotlib'de grafiğin altına küçük bir not eklemek için şu satır kullanılır.
- Python:
fig.text(0.01, 0.01, "Kaynak: Dünya Bankası, 28.09.2026'da indirildi.", fontsize=8) - R:
+ labs(caption = "Kaynak: Dünya Bankası, 28.09.2026'da indirildi.")
fig.text'teki ilk iki sayı, notun konumunu grafiğin sol alt köşesine göre, grafiğin genişliğinin ve yüksekliğinin kesri olarak belirtir. ggplot2'deki caption ise notu grafiğin sağ altına kendiliğinden yerleştirir.
Grafiği kaydederken dosya biçimi de önemlidir. PNG gibi raster biçimler grafiği piksellerden oluşan bir görüntü olarak saklar; büyütüldüğünde bulanıklaşır. PDF ve SVG gibi vektör biçimler ise çizgileri ve yazıları matematiksel olarak tanımlar ve her boyutta keskin kalır. matplotlib'de biçim, dosya adının uzantısından anlaşılır: fig.savefig("grafik.pdf") ya da fig.savefig("grafik.svg"). R'da ggsave("grafik.pdf") aynı işi görür. Bu satırlar çalıştırıldığında, iki vektör dosyası da sorunsuz oluştu.
Grafiği bir betikle üretmenin asıl üstünlüğü, veri güncellendiğinde grafiğin de tek komutla yeniden üretilebilmesidir. Bir hesap tablosunda elle biçimlendirilmiş bir grafik, her güncellemede yeniden düzenlenmek zorundadır; betikteki grafik ise başlığı, eksenleri, notu ve biçimiyle birlikte her seferinde aynı biçimde çizilir. Otomatik raporlamanın temeli budur; o konuya kursun sonlarına doğru döneceğiz.
Modelin sınırları
Bu derste temel grafik türlerini ve algı ilkelerini gördük. Etkileşimli grafikler, haritalar, ağ grafikleri ve animasyonlar gibi ileri görselleştirme araçları burada ele alınmadı; her biri kendi kütüphanesini ve tasarım ilkelerini gerektirir. Ayrıca grafik tasarımının bazı yönleri, örneğin renk paletlerinin seçimi ve yazı tipleri, kurumların kendi biçim kurallarına da bağlıdır.
Cleveland ile McGill'in sıralaması, okurun bir grafikten sayısal değer çıkarma doğruluğunu ölçer; bir grafiğin dikkat çekiciliğini, akılda kalıcılığını ya da duygusal etkisini değil. Bazı durumlarda, örneğin bir kamuoyu sunumunda, bu özellikler de önemli olabilir. Python örnekleri matplotlib'in 3.9 sürümüyle çalıştırılıp çıkan grafikler gözle denetlendi; ggplot2 satırları, bu makinede R bulunmadığı için belgelere dayanarak yazıldı.
Uygulama
Özet kartı
- Bir grafik, verideki değerleri konum, uzunluk, açı, alan ya da renk gibi görsel özelliklerle kodlar; Cleveland ile McGill'e göre ortak bir eksen üzerindeki konum en doğru okunan kodlamadır, alan ve renk tonu ise daha alt sıralardadır.
- Cleveland ile McGill, pasta ve bölünmüş çubuk grafikler gibi yaygın grafiklerde köklü değişiklikler gerektiğini savundu ve yerlerine nokta grafiklerini önerdi; Heer ile Bostock, grafik algısı deneylerinin kitle kaynaklı olarak tekrarlanabildiğini gösterdi.
- Python'da matplotlib grafiği adım adım çizer; John Hunter'ın beyin dalgası verileriyle çalışırken başlattığı bu kütüphane, MATLAB'ın çizim yeteneklerini taklit ederek doğdu. R'daki ggplot2 ise Wickham'ın katmanlı grafik dilbilgisine dayanır ve grafiği estetik eşlemeler ve katmanlarla kurar.
- Varsayılan ayarlar veriyi bilmez: yıllık bir seride yarım yıllar gösterebilir ya da uygun olmayan bir eksen seçebilir; çubuk grafikte eksen sıfırdan başlamalı, logaritmik ölçek oranları, küçük çoklular grupları karşılaştırmayı kolaylaştırır.
- Keşifsel grafikler analizcinin kendisi içindir ve veri hatalarını bulmaya yarar; açıklayıcı grafikler ise bulguyu söyleyen bir başlık, açık eksen etiketleri ve verinin kaynağını ve indirme tarihini gösteren bir notla birlikte hazırlanmalıdır.
Kavram sözlüğü
| Türkçe | İngilizce | Kısa tanım |
|---|---|---|
| Görsel kodlama | Visual encoding | Bir değerin konum, uzunluk, açı, alan ya da renk gibi görsel bir özelliğe dönüştürülmesi |
| Temel algısal görev | Elementary perceptual task | Bir grafikten değer okurken yapılan konum, uzunluk, açı ya da alan karşılaştırması gibi yargı |
| Grafik dilbilgisi | Grammar of graphics | Bir grafiği veri, eşleme, geometri, ölçek ve paneller gibi bileşenlere ayıran çerçeve |
| Estetik eşleme | Aesthetic mapping | Bir değişkenin eksen, renk ya da boyut gibi bir görsel özelliğe bağlanması |
| Küçük çoklular | Small multiples | Aynı ölçekteki küçük grafiklerin, her biri bir alt grubu gösterecek biçimde dizilmesi |
| Keşifsel grafik | Exploratory graphic | Analizcinin veriyi anlamak ve hataları bulmak için kendisi için çizdiği hızlı grafik |
Kendini sına
- (Çıktı 1) Görsel kodlama ile temel algısal görev arasındaki ilişkiyi açıkla. Aynı veri, bir pasta grafikte ve bir nokta grafiğinde hangi görsel özelliklerle kodlanır?
- (Çıktı 2) Cleveland ile McGill'in sıralamasına göre, birbirine yakın beş payı göstermek için pasta grafik yerine neden sıralanmış bir nokta grafiği önerilir? Heer ile Bostock'un çalışması bu bulguların güvenilirliği hakkında ne söyler?
- (Çıktı 3) Python'da bir veri çerçevesindeki yil ve enflasyon sütunlarıyla bir çizgi grafiği çizen, yatay eksende yalnızca gerçek yılları gösteren, sıfırda bir yatay çizgi ekleyen ve grafiği PDF olarak kaydeden satırları yaz.
- (Çıktı 3) R'da ggplot2 ile, ulke, yil ve enflasyon sütunları olan bir veri çerçevesinden her ülke için ayrı bir panel çizen grafiği yaz. Panellerin kendi dikey eksenlerini kullanmasını nasıl sağlarsın ve bunun okur açısından sakıncası nedir?
- (Çıktı 4) Bir raporda iki bölgenin geliri 100 ve 104 olarak bir çubuk grafikte gösterilmiş ve dikey eksen 98'den başlıyor. Okur, iki çubuk arasındaki farkı nasıl algılar? Bu grafik nasıl düzeltilmeli? Aynı veri bir çizgi grafiğinde gösterilseydi eksen seçimi için kural aynı mı olurdu?
- (Çıktı 4) Bir tasarım toplantısında şu söyleniyor: «Grafik seçimi zevk meselesidir; herkes beğendiği grafiği kullanır» diyor. Cleveland ile McGill'in ve Heer ile Bostock'un bulgularını kullanarak bu görüşü değerlendir.
Cevaplar
- Görsel kodlama, verideki bir değerin grafikte bir görsel özelliğe dönüştürülmesidir; temel algısal görev ise okurun bu görsel özellikten değeri geri çıkarmak için yaptığı yargıdır. Kodlama seçimi, okurun hangi görevi yapacağını belirler. Pasta grafik payları dilimlerin açısı ve alanıyla kodlar; okur açıları ve alanları karşılaştırmak zorundadır. Nokta grafiği ise payları ortak bir eksen üzerindeki konumla kodlar; okur konumları karşılaştırır.
- Cleveland ile McGill'in sıralamasında ortak bir eksen üzerindeki konum, en doğru okunan kodlamadır; alan daha alt sıralardadır. Birbirine yakın beş pay pasta grafikte benzer büyüklükte dilimler olarak görünür ve hangisinin büyük olduğu zor okunur. Sıralanmış bir nokta grafiğinde ise her pay ortak eksende bir konuma karşılık gelir ve küçük farklar bile görülebilir. Heer ile Bostock, önceki grafik algısı çalışmalarını çok daha büyük ve farklı bir katılımcı grubuyla tekrarladı ve kitle kaynaklı deneylerin uygulanabilir olduğunu gösterdi; bulguların farklı örneklemlerde tekrarlanabilmesi, güvenilirliklerini artırır.
- Satırlar şunlardır: fig, ax = plt.subplots(); ax.plot(df["yil"], df["enflasyon"], marker="o"); ax.set_xticks(df["yil"]); ax.axhline(0, color="gray", linewidth=0.8); ax.set_ylabel("Yüzde"); fig.savefig("enflasyon.pdf", bbox_inches="tight"). set_xticks, yatay eksende yalnızca verideki yılların görünmesini sağlar; PDF uzantısı, grafiğin vektör biçiminde kaydedilmesini sağlar.
- ggplot(df, aes(x = yil, y = enflasyon)) + geom_line() + facet_wrap(~ ulke) satırı, her ülke için ortak eksenli ayrı bir panel çizer. Panellerin kendi dikey eksenlerini kullanması için facet_wrap(~ ulke, scales = "free_y") yazılır. Bunun sakıncası, okurun paneller arasında düzeyleri doğrudan karşılaştıramamasıdır: yüksek enflasyonlu bir ülke ile düşük enflasyonlu bir ülkenin panelleri benzer yükseklikte çizgiler gösterebilir. Bu yüzden serbest eksen kullanıldığında bu durum okura açıkça belirtilmelidir.
- Eksen 98'den başladığı için A'nın çubuğu 2, B'nin çubuğu 6 birim uzunlukta çizilir; okur B'yi A'nın yaklaşık üç katı algılar, oysa fark yüzde 4'tür. Çubuk grafikte değer uzunlukla kodlandığı için eksen sıfırdan başlamalıdır. Çizgi grafikte ise değer konumla kodlanır ve okur çoğu zaman değişime bakar; eksen, verinin değişim aralığını okunur kılacak biçimde seçilebilir, ama bu seçim okura açıkça gösterilmelidir. Kural, grafik türüne göre değişir.
- Görüş yanıltıcıdır. Cleveland ile McGill, insanların grafiklerden değer okurken yaptığı görevlerin doğruluğunu deneylerle ölçtü ve bazı kodlamaların, örneğin ortak eksen üzerindeki konumun, açı ve alandan daha doğru okunduğunu gösterdi. Heer ile Bostock, bu tür bulguların çok daha büyük katılımcı gruplarında tekrarlanabildiğini gösterdi. Dolayısıyla grafik seçiminin bir kısmı zevk meselesi değil, ölçülebilir bir doğruluk meselesidir. Renk paleti ya da yazı tipi gibi bazı tercihler estetik olabilir, ama bir değerin hangi görsel özellikle kodlanacağı, okurun onu ne kadar doğru okuyacağını belirler.
İleri okuma
- William S. Cleveland, Robert McGill (1984). «Graphical Perception: Theory, Experimentation, and Application to the Development of Graphical Methods». Journal of the American Statistical Association 79(387). Grafik algısının kuramı ve deneyleri.
- Jeffrey Heer, Michael Bostock (2010). «Crowdsourcing Graphical Perception: Using Mechanical Turk to Assess Visualization Design». Proceedings of the SIGCHI Conference on Human Factors in Computing Systems. Grafik algısı deneylerinin kitle kaynaklı tekrarı.
- Hadley Wickham (2010). «A Layered Grammar of Graphics». Journal of Computational and Graphical Statistics 19(1). ggplot2'nin dayandığı katmanlı grafik dilbilgisi.
- Leland Wilkinson (2005, 2. baskı). The Grammar of Graphics. Springer. Grafik dilbilgisi yaklaşımının kaynağı.
Sonraki derse köprü
Grafikler, verinin biçimini gösterir; ama bir bulguyu kesin biçimde ifade etmek için çoğu zaman sayılara da ihtiyaç duyarız: bir dağılımın ortası, yayılımı, grupların birbirinden farkı. Sıradaki ders betimsel analizi ele alıyor. Python ve R ile ortalama, medyan ve yüzdelikler gibi özet istatistikler nasıl hesaplanır? Veriyi gruplara ayırıp her grup için özet çıkarmak, ağırlıklı ortalama almak ve iki değişkenin birlikte dağılımını bir çapraz tabloyla göstermek nasıl yapılır?