AST415 Astronomide Sayısal Çözümleme - I

Ders - 06 Grafik Çizimi

Doç. Dr. Özgür Baştürk
Ankara Üniversitesi, Astronomi ve Uzay Bilimleri Bölümü
obasturk at ankara.edu.tr
http://ozgur.astrotux.org

Matplotlib Kütüphanesi

PyPlot Modülü

Python’da grafik çizdirmek için $matplotlib$ kütüphanesinde yer alan ve $matplotlib$ ’in $MATLAB$ stilinde grafik üretmesini sağlayan komutların bir koleksiyonu olarak tanımlanabilecek $matplolib.pyplot$ modülü sıklıkla kullanılmaktadır. Matplotlib kütüphanesinin bazı çok önemli avantajlarının bulunması sebebiyle kullanımı oldukça yaygındır. Bu önemli avantajlar:

  • Kolay kullanımı,
  • $\LaTeX$ sembollerinin kullanılabilmesi,
  • Programlanabilir olması nedeniyle grafikler ve stilleri üzerinde geniş kontrol şansı vermesi,
  • Pe çok türde (PNG, PDF, SVG, EPS, ...), yüksek yayın kalitesinde çıktı üretebilmesi,
  • Grafikleri detaylı inceleyebilmek için basit bir arayüz (GUI) sağlaması

olarak sıralanbilir. Matplotlib oldukça hacimli bir modül olup, hakkında geniş bilgiye http://matplotlib.org/ adresinden ulaşılabilir.

Aşağıdaki kod parçasında basit bir örnek görülmektedir.

In [4]:
from matplotlib import pyplot as plt
# matplotlib grafiklerinin juypyter'da goruntulenebilmesi icin
# %matplotlib inline sihirli kelimesi (ing. magic keyword) verilmelidir
%matplotlib inline
plt.plot([1,2,3,4])
plt.xlabel("x")
plt.ylabel("y")
plt.show()

Gördüğünüz grafik yukarıdaki Python kodunun çıktısıdır. İstediğiniz formatta kaydedip saklayabilir, ya da üzerinde istediğiniz bölümüne yaklaştırma (ing.zoom-in) ya da uzaklaştırma (ing. zoom-out) yapabilirsiniz. $PyPlot$'un $plot$, $xlabel$ ve $ylabel$ fonksiyonları sırasıyla bir grafik (tek bir dizi (liste ya da demet) verildiğinde, $y$-ekseni değeri olarak alınır, $x$-ekseninin varsayılan listesi 0'dan başlar ve $y$-eksenini oluşturan dizi kadar eleman içerir), $x$ ve $y$ eksenleri için birer başlık nesnesini varsayılan parametrelerle oluşturur. $show()$ metodu ise onu ekrana getirir!

Çizdirilmek istenen grafik iki eksen (x ve y eksenleri) için ayrı ayrı tanımlanan iki veri grubu üzerinden çizilecekse her iki eksene ilişkin veri sağlanmalıdır.

In [6]:
# sembol turunu mavi bir cizgi yerine 
# kirmizi (r) bir ici dolu daire (o) olarak tanimlayalim
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
# x ve y eksenlerini daha iyi bir gorunum icin sinirlayalim
plt.axis([0, 6, 0, 20]) 
plt.show()

Görüldüğü üzere grafiğin eksen limitlerini belirlemek üzere $axis$ metodunu kullandık. Alternatif olarak $plt.xlim((0,6))$ ve $plt.ylim((0,20))$ şeklinde demet (ya da istenirse liste) nesneleriyle limitlerin tanımlandığı iki metod da kullanılabilir. $plot$ ifadesinde "$ro$" şeklinde bir metinle verilen ise noktaların şeklini "o" rengini kırmızı (red) belirleyen bir parametredir. "$b+$" aynı şekilde noktaları mavi birer "$+$" işareti ile gösterecektir (deneyiniz!).

Başa Dön

Birkaç Grafiği Aynı Anda Çizdirmek

$PyPlot$ modülünde birkaç eğriyi aynı anda tek bir grafik üzerine çizdirebilmek için grafikleri sırayla çizdirip, en sonunda göstermek ($show()$) yapılması gereken bir şey yoktur.

In [7]:
import numpy as np
# 0 ile 5 arasinda 0.2 esit araliklarla ayrilmis noktalarimiz olsun
t = np.arange(0., 5., 0.2)
# Asagidaki her bir grafigi farkli bir renk ve sembolle gosterelim
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

$PyPlot$ modülü ile birkaç grafiği aynı şeklin (pencerenin) farklı yerlerine de çizdirmek mümkündür.

In [8]:
def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

Burada $figure(1)$ bir şekil nesnesi oluşturmak için kullanılan bir metottur. $subplot$ ise her bir grafik için şekil üzerinde bir grafik nesnesi oluşturur. ($211$) bu şekil nesnesi üzerinde $2.$ satır ve $1.$ sütunda grafik oluşturacağımızı, bu grafiğin $1$ numaralı grafik olduğunu, $(212$) ise bu grafiğin $2.$ satır $1.$ sütundaki $2$ numaralı grafik olduğunu göstermektedir. Eğer bu grafikleri bir satır ve iki sütunda oluşturmak isteseydik birncisini ($121$), ikincisini ($122$) ile oluşturmamız gerekecekti. Gördüğünüz gibi "$k$" siyah renk için kullanılmakta, sembol türü için herhangi bir tercih yapılmadığında kesiksiz bir eğri, "$--$" kullanıldığında ise kesikli bir eğri çizdirilmektedir.

$PyPlot$ modülünde birkaç eğriyi aynı anda farklı iki şeklin (çerçeve) farklı yerlerine de çizdirebilirsiniz.

In [16]:
# birinci sekil
plt.figure(1) 
# ilk grafik
grafik1 = plt.subplot(121)
grafik1.plot([1,2,3])
# ikinci grafik
grafik2 = plt.subplot(122) 
grafik2.plot([4,5,6])
# ikinci sekil, ilk grafik varsayilan olarak (111) 
plt.figure(2) 
grafik3 = plt.plot([4,5,6])   
# birinci sekil ikinci grafigin basligini belirleyelim
plt.figure(1)          
plt.title('Python Ogreniyorum')
# grafiklerimizi gosterelim
plt.show()

PyPlot ve Metin Yönetimi

$Pyplot$ grafikleri üzerinde metin yönetimi oldukça kolaydır. Başlıklar, $title$, $xlabel$ ve $ylabel$ fonksiyonları ile yönetilirken, grafiğin herhangi bir yerine metin $text$ fonksiyonu ile $(x,y)$ koordinatları grafik biriminde verilerek yerleştirilir. $text$ fonksiyonu $\LaTeX$ sembolleri kullanabilmek de dahil olmak üzere pek çok özellik sağlar.

In [19]:
# Bir Histogram cizmek uzere verimizi olusturalim
# Ortalama (mu) ve standart sapma (sigma)
# degerlerimizi verelim
mu, sigma = 100, 15
# np.random fonksiyonu randn ile 10000 tane
# rastgele sayidan olusan bir dizi yaratalim
x = mu + sigma * np.random.randn(10000)
# verimizden bir histogram olusturalim
n, bins, patches = plt.hist(x, 50, density=1, \
facecolor='g', alpha=0.75)
# x eksenine bir baslik verelim
plt.xlabel('Zeka')
# y eksenine bir baslik verelim
plt.ylabel('Olasilik')
# grafigimize bir baslik verelim
plt.title('IQ Histogrami')
# ortalama ve standart sapmayi gosterelim
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
# eksen sinirlarimizi belirleyelim
plt.xlim((40,160))
plt.ylim((0,0.03))
# grid (izgara) gosterelim
plt.grid(True)
plt.show()

$PyPlot$ grafiklerinde grafikteki noktalarınızı $annotate$ fonksiyonunu kullanarak etiketleyebilirsiniz.

In [29]:
# t eksenini numpy arange fonksiyonu ile olusturalim
t = np.arange(0.0, 5.0, 0.01)
# s = cos(2 * PI * t) ifadesiyle fonksiyonumuzu olusturalim
s = np.cos(2*np.pi*t)
# grafigimizi cizdirelim
plt.plot(t, s, lw=2)
# noktamizi etiketleyelim
plt.annotate('yerel maksimum', xy=(2, 1), xytext=(3, 1.5),
            arrowprops=dict(facecolor='black', shrink=0.05),)
# y ekseninin limitlerini belirleyelim
plt.ylim(-2,2)
plt.show()

Eğri Uyumlama

Basit Bir Doğru Uyumlama Örneği

$NumPy$ ve $PyPlot$ fonksiyonlarını kullanarak gözlemsel veriye bir eğri uyumlayabilir ve bunu grafik üzerinde gösterebiliriz. Basit bir doğru uyumlama örneği ile başlayalım.

In [31]:
# x ve y eksenleri birer liste olarak olusturulmus olsun
x = [-7.30000, -4.10000, -1.70000, -0.02564,
     1.50000, 4.50000, 9.10000]
y = [-0.80000, -0.50000, -0.20000, 0.00000,
     0.20000, 0.50000, 0.80000]
# NumPy polyfit fonksiyonuna x ve y degerlerini
# ve dogru uyumlayacagimizi (1) soyleyelim
katsayilar = np.polyfit(x, y, 1)
# polyfit polinom katsayilarini hesaplar bu katsayilari poly1d'ye 
# verilirse bulunan katsayilara gore bir polinom fonksiyonu 
# yaratilir. x degerlerine denk gelen dogrusal y degerleri 
# hesaplanir
polinom = np.poly1d(katsayilar)
y_polinom = polinom(x)
print("Polinomun katsayilari: ", katsayilar)
print("Polinom: ", polinom)
plt.plot(x, y, 'o')
plt.plot(x, y_polinom)
plt.ylabel('y')
plt.xlabel('x')
plt.xlim(-10,10)
plt.ylim(-1,1)
plt.show()
Polinomun katsayilari:  [ 0.10160693 -0.02865838]
Polinom:   
0.1016 x - 0.02866

Yüksek Dereceden Polinom Uyumlama

Şimdi de gözlemsel veriye 6. dereceden bir eğri uyduralım.

In [32]:
# x'e karsilik y seklinde gozlemsel veri:
x = [2.53240, 1.91110, 1.18430, 0.95784, 0.33158,
     -0.19506, -0.82144, -1.64770, -1.87450, -2.2010]
y = [-2.50400, -1.62600, -1.17600, -0.87400, -0.64900,
     -0.477000, -0.33400, -0.20600, -0.10100, -0.00600]
# 6. dereceden polinom fitinin katsayilari
katsayilar = np.polyfit(x, y, 6)
polinom_6 = np.poly1d(katsayilar)
# 0.1 araiklarla yeni bir x ekseni
x_polinom6 = np.arange(-2.2, 2.6, 0.1)
y_polinom6= polinom_6(x_polinom6)
# Grafik cizimi
plt.plot(x, y, 'o')
plt.plot(x_polinom6, y_polinom6)
plt.ylabel('y')
plt.xlabel('x')
plt.show()

PyPlot Dekorasyon Parametreleri

Aşağıda verilen tüm dekorasyon parametrelerinin kombinasyonlarını da kullanabilirsiniz. Örneğin "$kx$" siyah renkli çarpı işaretleri, "$m--$ mor" (magenta) renkli kesikli eğri anlamına gelir!

Renkler

Grafiklerinizi dekore etmek üzere aşağıdaki renklere ingilizce isimlerinin baş harfleriyle ulaşabilirsiniz:

Sarı: “y” ,
Mor: “m” ,
Açık mavi: “c”,
Kırmızı: “r” ,
Mavi: “b” ,
Beyaz: “w” ,
Mavi: “k”

Eğri Türleri

Grafiklerinizde kullanacağınız eğrilere aşağıdaki stilleri uygulayabilirsiniz:

Kesiksiz Eğri: "-" (varsayılan),
Kesikli Eğri: "--",
Noktalı Eğri: ":",
Kesikli Noktalı Eğri: "-."

Sembol Stilleri

Grafiklerinizde kullanacağınız noktalara aşağıdaki stilleri uygulayabilirsiniz:

Artı işareti "+",
İçi dolu yuvarlak: "o",
Yıldız "*",
Nokta: ".",
Çarpı işareti: "x" ,
İçi dolu kare: "s" ,
İçi dolu baklava dilimi: "d" ,
Bir köşesi yukarıya bakan üçgen: "^",
Bir köşesi aşağıya bakan üçgen: "v",
Bir köşesi sağa bakan üçgen: ">",
Bir köşesi sola bakan üçgen: "<",
Beş köşeli yldız (pentagram): "p",
Altı köşeli yıldız (hexagram): "h"

Alıştırmalar

  1. Dikey atış problemini $y_{0} = 0$, $V_{0} = 10 m/s$, $g = 9.81 m/s^2$ için aşağıdaki ifadeden faydalanarak $t \in [0, 2V_0 / g]$ aralığında eşit aralıklı a) 10, b)100 zaman ($t$) değeri için çözünüz ve zamana ($t$) karşılık yükseklik ($y$) grafiğini mavi kesiksiz eğri ile iki ayrı grafikte çiziniz.
$$ y = y_0 + V_0 t - \frac{1}{2} g t^2 $$

Grafiğin eksenlerini $zaman (s)$ ve $yukseklik (m)$, başlığını $Dikey Atis Problemi$ olarak adlandırınız.

  1. Fahrenheit dereceden Santigrad dereceye hızlı bir dönüşüm C = (F - 30) / 2 formülüyle yapılabilir. $[20, 120]$ kapalı aralığında birbirinden eşit uzaklıkta 250 Fahrenheit dereceyi bu formülle ve standart dönüşüm formülüyle (C = 9 / 5 * (F - 32) + 180) Santigrad dereceye dönüştürünüz. Oluşan Santigrad derece değerlerini Fahrenheit dereceye karşılık çizdirerek (standart dönüşüm mavi kesiksiz doğru, yaklaşık dönüşümü kırmızı noktalı-kesikli doğru) yaklaşık formülün başarısını karşılaştırma yoluyla test ediniz.

  2. Bir önceki soruda oluşturulan grafikte görüldüğü gibi iki ifade belirli bir fahrenheit değerinde eşit olmakta (doğrular kesişmekte) ve bu doğrudan uzaklaştıkça yaklaşık ifade tam ifadeden giderek uzaklaşmaktadır. Bu değeri bularak, grafik üzerinde yeşil, içi dolu bir kare ile gösteriniz.

  3. $V_0$ hızı ile yatayla $\theta$ açı yapacak şekilde $g$ yerçekim ivmeli ortamda fırlatılan bir cismin izleyeceği yol aşağıdaki formülle verilir.

$$ y = x tan(\theta) - \frac{1}{2 V_0^2} \frac{g x^2}{cos^2 \theta} + y_0 $$

Verilen bu ifadeyi $g = 9.81$ ve $y_0 = 0$ parametrelerini bu varsayılan değerlerle anahtar kelime argümanları, diğer tüm parametreleri ($x$, $\theta$, $V_0$) ise konum argümanı olarak alan, $yatay\_atis$ adında bir fonksiyon olarak kodlayınız.

Burada x cismin yatay eksendeki koordinatı, y ise yüksekliğidir. $x \in [0, \frac{V_{0}^2 sin 2 \theta}{g}]$ aralığında oluşturacağınız a) 10 $x$ değeri için ($x_1$) cismin aldığı yolu (x'e karşılık y) kırmızı kesiksiz doğru, b) 100 $x$ değeri için ($x_2$) ise yeşil noktalı doğru ile çizdiriniz. $V_0 = 10$ m/s, $\theta = \pi / 6$ radyan alınız.

Cismin maksimum yüksekliğe çıktığı andaki x koordinatını ($xmax$) $\frac{V_0^2 sin 2\theta}{2 g}$ formülünden hesaplattıktan sonra $yatay\_atis$ fonksiyonunuzda yerine koyarak y koordinatını ($ymax$) bulunuz ve grafiğinizde bu ($xmax$, $ymax$) koordinatını mavi bir baklava dilimi (ing. diamond) işareti ile işaretleyiniz.

  1. $L$ uzunluğunda kütlesiz bir sarkaç ipine bağlı $m$ kütlesi $T$ salınma dönemiyle salınıyor olsun. Aşağıda farklı uzunluklardaki sarkaçlarla yapılan salınma dönemi ölçümleri birer $numpy$ dizisi ile verilmiştir. L dizisine karşılık T dizisini kırmızı içi dolu dairelerle çizdiriniz. L ile T arasındaki ilişkinin sırasıyla 1, 2, ve 3. dereceden polinomlarla ifade edilebileceğini varsayarak ve $np.polyfit$ ile $np.poly1d$ fonksiyonlarını kullanarak elde edeceğiniz polinomları gözlemsel noktalarınızın üzerine çizdiriniz. Sizce hangi dereceden polinom veriyi daha iyi temsil etmektedir?

Başa Dön