Grafiklemek, Matplotlib, Pandas
Basit X-Y grafikleri, ikili, üçlü, iki eksenli, üç boyutlu grafikleri bu yazıda işleyeceğiz.
Giriş
En basit grafik,
import matplotlib.pyplot as plt
x = np.linspace(-10,10,100)
y = np.sin(x)
plt.plot(x,y)
plt.savefig('graf_01.png')
Önceki metot tüm noktaları birleştiriyor. Eğer birleştirilmesini
istemesek nokta nokta olarak her veri öğesinin basılmasını istesek
plot
içinde .
kullanırdık.
plt.plot(x,y,'r.')
plt.savefig('graf_02.png')
Renkleri de aynı komutta belirtilebiliyoruz. Üstteki r
kırmızı (red) için.
Eksenler
Çoğu zaman aynı imajda birden fazla grafik olmasını isteyebiliyoruz, karşılaştırma amacıyla, vs. Alt alta iki grafik için çabuk bir şekilde
x2 = x+100
y1 = np.cos(x2) + 3*np.sin(x2)
y2 = np.exp(x)
fig, axs = plt.subplots(2)
axs[0].plot(x2,y1)
axs[1].plot(x,y2)
plt.savefig('graf_03.png')
Üstteki örnekte x ekseni farklı, çünkü değerlerin skalası farklı o şekilde grafiklemek istedik. Fakat bazen de aynı x skalası üzerinden farklı grafikler basmak isteyebiliriz,
y1 = np.cos(x) + 3*np.sin(x)
y2 = np.exp(x)
fig, axs = plt.subplots(2,sharex=True)
axs[0].plot(x,y1)
axs[1].plot(x,y2)
plt.savefig('graf_04.png')
Eğer Pandas üzerinden grafikleme yapılıyorsa onun plot(ax=..)
komutuna dışarıdan axs[0]
, axs[1]
vs verilebiliyor.
Pandas ile bu arada çoğu grafikleme iyice basit hale geliyor, mesela
bir DataFrame
içinde iki kolon olsun, basmak için direk DataFrame
üzerinde plot
çağırmak yeterli,
import pandas as pd
x = np.linspace(0,10,100)
df = pd.DataFrame(index=x)
df['y1'] = np.cos(x)
df['y2'] = np.sin(x)
df.plot()
plt.savefig('graf_05.png')
Grafikler direk çizildi, her kolon için ayrı grafik olmak üzere, renklendirildi, ve kolon isimleri bile grafiğin içine yazıldı!
Eğer üstteki gibi bir grafiği ama y ekseninde farklı skala olacak şekilde basmak istesek ne yapardık? Mesela bir grafik sıcaklık, diğeri nem miktarı, bunlar farklı skalalarda olabilir ama trendlerini aynı grafikte aynı x skalası üzerinden (mesela tarih) görmek faydalı olabilir.
import pandas as pd
x = np.linspace(0,10,100)
plt.figure(figsize=(5,3))
df['y1'] = np.cos(x)
df['y2'] = np.sin(x) + 100.0
ax1 = df.y1.plot(color='blue', grid=True, label='y1')
ax2 = df.y2.plot(color='red', grid=True, label='y2',secondary_y=True)
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
plt.legend(h1+h2, l1+l2, loc=2)
plt.savefig('graf_06.png')
Belli bölgeleri belli x değerleri için tüm y eksen bazında daha farklı renkte göstermek isteyebiliriz, mesela finansta ekonomik krizler zaman serisi üzerinde bu şekilde gösterilir. Örnek olarak ABD / Britanya Pound döviz kuru üzerinde görelim, ve iki krizi zamanını işaretleyelim,
import pandas as pd
df = pd.read_csv('DEXUSUK.csv',index_col=0,parse_dates=True)
df = df[df.index > '1995-01-01']
df.plot()
c = 'gainsboro' # acik gri rengi
plt.axvspan('01-03-2001', '27-10-2001', color=c, alpha=0.5, lw=0)
plt.axvspan('22-12-2007', '09-05-2009', color=c, alpha=0.5, lw=0)
plt.savefig('graf_07.png')
add_subplot(222)
?
Matplotlib (ve Matlab) ana grafik ekranini bolerek ufak grafikleri bu bolumlere koyma yetenegine sahip. Bu orneklere bakarken, belki de 332, 222 gibi sayilar kullanildigini gormussunuzdur. Mesela
fig = plt.figure()
ax1 = fig.add_subplot(321,title="baslik")
ax1.plot(data1)
gibi. Burada 321'in anlami sudur: Ana ekran 3 satir ve 2 kolon olmak uzere, yani 3x2 olarak bolunecek, ve ustteki grafik 1'inci bolume konacak.
1., 2. tabii ki sol ustten baslanip saga dogru gidince artan sayilar, yani hucrelerin indisi.
O zaman 321'in 32 kismi diger tum alt grafikler icin tekrarlanacak. Yeni grafikler 322, 323, 324, vs gibi gidecekler.
Farkli Bir Kolon Isaretleme Teknigi
Üstteki avxspan
ile indeks bazlı aralıkları işaretleyebiliyoruz. Eğer
herhangi bir kolon bazlı dikey işaretleme yapmak istesek bir diğer yöntem
fill_between
ile.
x = np.linspace(0,10,100)
y = np.cos(2*x)
crisis = (x > 3) & (x < 8).astype(int)
plt.plot(x,y)
plt.grid(True)
plt.fill_between(x, -1, 2, crisis, alpha=0.3)
plt.savefig('graf_08.png')
Böylece crisis
(kriz) kolonuna dayanarak eğer orada 1 var ise o alanı
dikey olarak işaretliyoruz, sıfır ise hiçbir şey gösterilmiyor.
Üç Boyut
Diyelim ki 3 boyutlu bir fonksiyon hesaplatacağız, fonksiyon alanı ise
x kordinatı -5 ve 5 arasında, y kordinatı -3, 3 arasında olacak. O
zaman bu aralıktaki her noktanın kombinasyonu bizen lazım. Bu
kombinasyon [-5,-3], [5.1,-3],..,[-5,-3.1]
diye gidecekti. Fonksiyon
meshgrid
2 kordinat vektörü alır ve geriye 2 kordinat matrisi
döndürür.
meshgrid
fonksiyonunun yaptığı bu kombinasyonu rahat erişilir hale
getirmekten ibaret. meşhgrid çağrısından geri gelecek X ve Y
matrislerinde X[1]
ve Y[1]
'e baktığımızda (her iki tarafta aynı
indisi kullandığımızda yani) kombinasyonlardan birini anında
alabileceğiz. Örnek
x = np.arange(-5, 5, 0.1)
y = np.arange(-3, 3, 0.1)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx**2+yy**2)/(xx**2+yy**2)
Not: Bu kodda meshgrid
'den gelen xx ve yy üzerinde direk indis
kullanılıyormuş gibi gözükmüyor, fakat arka planda aslında
kullanılıyor. xx ile yy üzerinde aritmetik işlemler kullanılınca, bu
otomatik olarak her xx ve yy elemanın teker teker, aynı indiste
olanlarının beraber işleme sokulması demektir, +, -, ** gibi işlemler
perde arkasında buna göre kodlanmıştır.
from matplotlib import cm
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, zz, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('graf_09.png')
Yukarı